zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    Bootstrap+Angularjs自制弹框
    【2019年04月22日】A股最便宜的股票
    沪深300指数的跟踪基金排名
    【2019年04月10日】股票的滚动市盈率PE最低排名
    【2019年04月09日】A股净资产收益率ROE最高排名
    基金 、社保和QFII等机构的重仓股排名评测
    【2019年04月04日】股市指数估值排名
    【2019年04月03日】A股最便宜的股票
    净资产收益率ROE连续3年超过15%的股票排名
    A股滚动净利润增速最高排名
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/10031313.html
Copyright © 2011-2022 走看看