zoukankan      html  css  js  c++  java
  • noi.acNOIP模拟赛5-count

    题目链接

    戳我

    题意简述

    你有一个n+1个数的序列,都是1~n,其中只有一个有重复,求每个长度的本质不同的子序列个数。(mod 1e9+7)

    sol

    说起来也很简单,设相同的数出现的位置为(l)(r)。那么除了去掉(r)之后(n)个数的贡献,还有算上(r)的贡献,然后就可以了。原本(n)个的贡献是(inom{n}{i}),加上(r)的贡献的话要满足在([l,r-1])之间至少要选一个数,然后还要选(r),那么考虑将原序列(去除(r))分成三段,([1,l-1],[l,r-1],[r+1,n+1]),可以枚举长度,发现是一个卷积,于是可以愉快的NTT辣,然后模数是(1e9+7)?

    md不管蒯一个三模数NTT暴力艹过去。总复杂度 $ O(nlogn) $ 。其实好像有 $ O(n) $ 做法,但我懒得想。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define gt getchar()
    #define ll long long
    #define maxn 400005
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    #define Set(a) memset(a,0,sizeof a)
    using std::swap;
    using std::reverse;
    inline int in()
    {
    	int k=0;char ch=gt;
    	while(ch<'-')ch=gt;
    	while(ch>'-')k=k*10+ch-'0',ch=gt;
    	return k;
    }
    int pr[]={469762049,998244353,1004535809};
    const int md=1e9+7,YL=md;
    inline ll ksm(ll a,ll b,ll p)
    {
    	ll r=1;a%=p;
    	while(b){if(b&1)r=r*a%p;a=a*a%p,b>>=1;}
    	return r;
    }
    int R[maxn];
    struct FFT
    {
    	int G,P,A[maxn];
    	void NTT(int* a,int n,int f)
    		{
    			for (int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);
    			for (int i=1;i<n;i<<=1)
    			{
    				int gn=ksm(G,(P-1)/(i<<1),P);
    				for(int j=0;j<n;j+=(i<<1))
    				{
    					int g=1,x,y;
    					for (int k=0;k<i;k++,g=1ll*g*gn%P)
    					{
    						x=a[j+k],y=1ll*g*a[j+k+i]%P;
    						a[j+k]=(x+y)%P,a[j+k+i]=(x+P-y)%P;
    					}
    				}
    			}
    			if(f==1)return;
    			int nv=ksm(n,P-2,P);reverse(a+1,a+n);
    			for(int i=0;i<n;i++)a[i]=1ll*a[i]*nv%P;
    		}
    }fft[3];
    int F[maxn],G[maxn],B[maxn],deg1,deg2,deg;
    ll ans[maxn];
    ll inv(ll n,ll p){return ksm(n % p,p - 2,p);}
    ll mul(ll a,ll b,ll p)
    {
    	ll re=0;
    	for(;b;b>>=1,a=(a+a)%p)
    		if(b&1)re=(re+a)%p;
    	return re;
    }
    void CRT()
    {
    	deg=deg1+deg2;
    	ll a,b,c,t,k,M=1ll*pr[0]*pr[1];
    	ll inv1=inv(pr[1],pr[0]),inv0=inv(pr[0],pr[1]),inv3=inv(M%pr[2],pr[2]);
    	for(int i=0;i<=deg;i++)
    	{
    		a=fft[0].A[i],b=fft[1].A[i],c=fft[2].A[i];
    		t=(mul(a*pr[1]%M,inv1,M)+mul(b*pr[0]%M,inv0,M))%M;
    		k=((c-t%pr[2])%pr[2]+pr[2])%pr[2]*inv3%pr[2];
    		ans[i]=((k%md)*(M%md)%md+t%md)%md;
    	}
    }
    void pre()
    {
    	int n=1,L=0;
    	while(n<=(deg1+deg2))n<<=1,L++;
    	for (int i=1;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
    	for (int u=0;u<=2;u++)
    	{
    		fft[u].G=3;fft[u].P=pr[u];
    		for(int i=0;i<=deg1;i++)fft[u].A[i]=F[i];
    		for(int i=0;i<=deg2;i++)B[i]=G[i];
    		for(int i=deg2+1;i<n;i++)B[i]=0;
    		fft[u].NTT(fft[u].A,n,1);fft[u].NTT(B,n,1);
    		for(int i=0;i<n;i++)fft[u].A[i]=1ll*fft[u].A[i]*B[i]%pr[u];
    		fft[u].NTT(fft[u].A,n,-1);
    	}
    }
    void get_mul(int *a,int *b,int *c,int n,int m)
    {
    	deg1=n;deg2=m;
    	for(int i=0;i<=deg1;++i)F[i]=a[i];
    	for(int i=0;i<=deg2;++i)G[i]=b[i];
    	pre();CRT();
    	for(int i=0;i<=deg;++i)c[i]=ans[i];
    }
    const int N=1e6+7;
    inline int ksm(int a,int k){int r=1;while(k){if(k&1)r=1ll*a*r%YL;a=1ll*a*a%YL,k>>=1;}return r;}
    int fac[N],fnv[N],ma[N],as[N];
    inline int C(int x,int y){return y>x?0:1ll*fac[x]*fnv[y]%YL*fnv[x-y]%YL;}
    inline int MO(const int &a){return a>=YL?a-YL:a;}
    int a[N],b[N],c[N];
    int main()
    {
    //	File("conut");
    	int n=in();fac[0]=fnv[0]=1;
    	for(int i=1;i<=n+1;++i)fac[i]=1ll*fac[i-1]*i%YL;
    	fnv[n+1]=ksm(fac[n+1],YL-2);
    	for(int i=n;i;--i)fnv[i]=1ll*fnv[i+1]*(i+1)%YL;
    	int l=1,r=n+1;
    	for(int i=1,u;i<=n+1;++i)
    	{
    		u=in();
    		if(ma[u])l=ma[u],r=i;
    		ma[u]=i;
    	}
    	for(int i=1;i<=n;++i)as[i]=C(n,i);
    	int l1=l-1,l2=r-l,l3=n-r+1;
    	for(int i=0;i<=l1;++i)a[i]=C(l1,i);
    	for(int i=1;i<=l2;++i)b[i]=C(l2,i);
    	get_mul(a,b,b,l1,l2);
    	Set(a),Set(ans),Set(F),Set(G),Set(fft);
    	for(int i=0;i<=l3;++i)a[i]=C(l3,i);
    	get_mul(a,b,b,l3,l1+l2);
    	for(int i=1;i<=n;++i)as[i+1]=MO(as[i+1]+b[i]);
    	for(int i=1;i<=n+1;++i)printf("%d
    ",as[i]);
    	return 0;
    }
    
    
  • 相关阅读:
    Framework 4.0 新关键字dynamic 之我见(二)
    随便歇歇
    最近的一些总结
    一周最新示例代码回顾 (7/16 7/22)
    一周最新示例代码回顾 (5/28–6/3)
    一周最新示例代码回顾 (5/14–5/20)
    一周最新示例代码回顾 (6/25 7/1)
    微软一站式示例代码浏览器本周更新发布
    一周最新示例代码回顾 (6/11 6/17)
    示例代码浏览器5.4功能更新
  • 原文地址:https://www.cnblogs.com/cx233666/p/9696359.html
Copyright © 2011-2022 走看看