• bzoj4361isn 容斥+bit优化dp


    4361: isn

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 375  Solved: 186
    [Submit][Status][Discuss]

    Description

    给出一个长度为n的序列A(A1,A2...AN)。如果序列A不是非降的,你必须从中删去一个数,
    这一操作,直到A非降为止。求有多少种不同的操作方案,答案模10^9+7。
     

    Input

    第一行一个整数n。
    接下来一行n个整数,描述A。

    Output

    一行一个整数,描述答案。

    Sample Input

    4
    1 7 5 3

    Sample Output

    18

    HINT

    1<=N<=2000

    先找出长度为i的非降序列方案数,对于每个方案在原序列中删除其它元素可得答案
    f[i][j]表示长度为i,以第j个元素结尾构成非降序列方案数
    转移n^3 bit优化至n^2*log2(n)
    g[i]表示长度为i的非降序列个数,可以对f[][]求和得到

    接下来考虑每个方案,在原序列中删除一些数来得到答案

    对于长度为i的非降序列,可以在原串中删去剩余的n-i个元素来得到
    由于删除是有顺序的,所以删除方案是 (n-i)!
    那么对于每个i,它贡献的答案就是g[i]*(n-i)!
    但是,由于有些删除方法到长度i+1时就应该停止,所以 -(n-i-1)!*(i+1)*g[i+1] 不管i+1合法或者非法,到i肯定不合法,所以减去
    *(i+1)是因为还要选择一个删去才得到长度i的序列
    那么ans=sum(g[i]*(n-i)!-(n-i-1)!*(i+1)*g[i+1])

     

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define ll long long
     6 #define mod 1000000007
     7 #define N 2005
     8 using namespace std;
     9 int a[N],b[N],fac[N],n;ll f[N][N],c[N],g[N];
    10 void plu(ll &x,ll y){
    11     x+=y;x>mod?x-=mod:1;
    12 }
    13 void update(int p,int val){
    14     while(p<=n){
    15         plu(c[p],val);
    16         p+=p&-p;
    17     }
    18 }
    19 ll sum(int p){
    20     ll t=0;
    21     while(p){
    22         plu(t,c[p]);
    23         p-=p&-p;
    24     }
    25     return t;
    26 }
    27 int main(){
    28     scanf("%d",&n);
    29     for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
    30     sort(b+1,b+1+n);
    31     int len=unique(b+1,b+1+n)-b-1;
    32     for(int i=1;i<=n;i++)
    33     a[i]=lower_bound(b+1,b+1+len,a[i])-b;
    34     for(int i=1;i<=n;i++)f[1][i]=1;
    35     for(int i=2;i<=n;i++){
    36         memset(c,0,sizeof(c));
    37         for(int j=1;j<=n;j++){
    38             plu(f[i][j],sum(a[j]));
    39             update(a[j],f[i-1][j]);
    40         }
    41     }
    42     for(int i=1;i<=n;i++)
    43     for(int j=1;j<=n;j++)
    44     plu(g[i],f[i][j]);
    45     ll ans=0;
    46     fac[0]=1;
    47     for(int i=1;i<=n;i++)fac[i]=(1ll*fac[i-1]*i)%mod;
    48     for(int i=n;i;i--)
    49     ans=(ans+(g[i]*fac[n-i])%mod-((g[i+1]*(i+1))%mod*fac[n-i-1])%mod)%mod;
    50     ans<0?ans+=mod:1;
    51     cout<<ans;
    52     return 0;
    53 }
  • 相关阅读:
    Weblogic学习笔记
    Shiro权限使用
    Shiro权限框架使用总结
    支付宝接口文档说明
    代码模拟实现十六进制转二进制
    代码模拟实现十六进制转换十进制
    四种内部类详细解释和代码示例
    Struts2_struts.xml写法和用法例子
    spring一些方法和用法例子
    Hibernate一些_方法_@注解_代码示例
  • 原文地址:https://www.cnblogs.com/wsy01/p/8099098.html
Copyright © 2020-2023  润新知