• [BZOJ4361]isn


    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


    我们设(f[i][j])表示以(i)结尾的长度为(j)的不下降子序列个数,借助树状数组可以用(O(n^2log n))的复杂度求出

    然后我们设(g[i]=sumlimits_{j=1}^nf[j][i]),表示长度为(i)的非降子序列个数,最后对答案的贡献为(Ans[i]=(n-i)! imes g[i])

    但这样统计答案是错误的,因为我们在枚举剩下的((n-i))个数的删除序列的时候,存在某一时刻序列已经非降,但是我们没有停下来

    考虑如果我们枚举到一个非法的删除序列,那么它一定是通过((i+1))个数删掉一个的得来的,所以我们容斥一下即可

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    #define lowbit(x) ((x)&(-x))
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)     print(x/10);
    	putchar(x%10+'0');
    }
    const int N=2e3,p=1e9+7;
    int f[N+10][N+10],tree[N+10][N+10],g[N+10],fac[N+10];
    ll val[N+10],list[N+10];
    int n,T;
    ll Ans;
    void insert(int x,int cnt,int v){for (;x<=n;x+=lowbit(x))	tree[x][cnt]=(tree[x][cnt]+v)%p;}
    int query(int x,int cnt){
    	int res=0;
    	for (;x;x-=lowbit(x))	res=(res+tree[x][cnt])%p;
    	return res;
    }
    int main(){
    	n=read();
    	for (int i=1;i<=n;i++)	val[i]=list[i]=read();
    	sort(list+1,list+1+n);
    	T=unique(list+1,list+1+n)-list-1;
    	for (int i=1;i<=n;i++)	val[i]=lower_bound(list+1,list+1+T,val[i])-list;
    	insert(1,0,1);
    	for (int i=1;i<=n;i++){
    		for (int j=i;j;j--){
    			f[i][j]=query(val[i],j-1);
    			insert(val[i],j,f[i][j]);
    		}
    	}
    	fac[0]=1;
    	for (int i=1;i<=n;i++)	fac[i]=1ll*fac[i-1]*i%p;
    	for (int i=1;i<=n;i++)	for (int j=1;j<=n;j++)	g[i]=(g[i]+f[j][i])%p;
    	for (int i=1;i<=n;i++)	Ans=((Ans+1ll*g[i]*fac[n-i]%p-1ll*g[i+1]*fac[n-i-1]%p*(i+1)%p)+p)%p;
    	printf("%lld
    ",Ans);
    	return 0;
    }
    
  • 相关阅读:
    es 报错cannot allocate because allocation is not permitted to any of the nodes
    linux下获取软件源码包 centos/redhat, debian/ubuntu
    windows假死原因调查
    k8s-calico
    helm使用
    docker网络模式
    4、formula 法则、原则、数学公式
    powershell自动添加静态IP
    WDS部署Windows server2012初试
    2、puppet资源详解
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/10031313.html
Copyright © 2020-2023  润新知