• bzoj 5306: [Haoi2018]染色


    Description

    Solution

    写了个傻逼的 (O(n+m*log^2)) 的做法,卡了一下午才过 (bzoj)
    首先设 (f[i]) 表示至少有 (i) 种颜色数量为 (s)
    显然 (f[i]=C_{m}^{i}*C_{n}^{i*s}*frac{(i*s)!}{s!^i}*m^{n-i*s})
    (g[i]) 表示至少有 (i) 种颜色数量为 (s)
    然后写出了个傻逼式子:
    (g[n]=f[n])
    (g[i]=f[i]-sum_{j=i+1}^{n}g[j]*C_j^i)
    然后分治(NTT),强行多一个 (log),实际上对 (f) 数组直接容斥就行了

    #include<bits/stdc++.h>
    #define RG register
    using namespace std;
    template<class T>void gi(T &x){
    	int f;char c;
    	for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
    	for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
    }
    const int N=1e7+10,M=1e5+10,mod=1004535809;
    int n,m,s,w[M],f[M],Fac[N],inv[N],g[M],lim,D,INV[N];
    inline int qm(int x,int k){
    	int sum=1;
    	while(k){
    		if(k&1)sum=1ll*sum*x%mod;
    		x=1ll*x*x%mod;k>>=1;
    	}
    	return sum;
    }
    inline int C(int a,int b){
    	return 1ll*Fac[a]*inv[b]%mod*inv[a-b]%mod;
    }
    int E,L=0,R[M*4],G[M*4];
    inline void NTT(int *A){
    	for(RG int i=0;i<E;i++)if(i<R[i])swap(A[i],A[R[i]]);
    	for(RG int i=1;i<E;i<<=1){
    		int t0=G[i],x,y;
    		for(RG int j=0;j<E;j+=i<<1){
    			int t=1;
    			for(RG int k=0;k<i;k++,t=1ll*t*t0%mod){
    				x=A[j+k];y=1ll*A[j+k+i]*t%mod;
    				A[j+k]=(x+y)%mod;A[j+k+i]=(x-y+mod)%mod;
    			}
    		}
    	}
    }
    inline void mul(int *A,int *B){
    	NTT(A);NTT(B);
    	for(RG int i=0;i<=E;i++)A[i]=1ll*A[i]*B[i]%mod;
    	NTT(A);
    	reverse(A+1,A+E);
    	for(RG int i=0,t=INV[E];i<=E;i++)A[i]=1ll*A[i]*t%mod;
    }
    int A[M*4],B[M*4];
    inline void solve(int l,int r){
    	if(l==r){
    		f[lim-l]=(f[lim-l]-1ll*g[l]*inv[lim-l]%mod+mod)%mod;
    		return ;
    	}
    	int mid=(l+r)>>1,len=(r-l+1);
    	solve(l,mid);
    	L=0;
    	for(E=1;E<=len;E<<=1)L++;
    	for(RG int i=0;i<E;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1)),A[i]=0,B[i]=inv[i];
    	for(RG int i=l;i<=mid;i++)A[i-l]=1ll*f[lim-i]*Fac[lim-i]%mod;
    	mul(A,B);
    	for(RG int i=mid+1;i<=r;i++)g[i]=(g[i]+A[i-l])%mod;
    	solve(mid+1,r);
    }
    int main(){
    	freopen("pp.in","r",stdin);
    	freopen("pp.out","w",stdout);
    	cin>>n>>m>>s;INV[0]=INV[1]=1;G[1]=qm(3,(mod-1)/2);
    	for(RG int i=2;i<400000;i++){
    		G[i]=qm(3,(mod-1)/(i<<1));
    		INV[i]=(mod-1ll*(mod/i)*INV[mod%i]%mod)%mod;
    	}
    	for(RG int i=0;i<=m;i++)gi(w[i]);
    	lim=min(n/s,m),D=max(n,m);
    	Fac[0]=inv[0]=inv[1]=INV[0]=INV[1]=1;
    	for(RG int i=1;i<=D;i++)Fac[i]=1ll*Fac[i-1]*i%mod;
    	inv[D]=qm(Fac[D],mod-2);
    	for(RG int i=D-1;i>=2;i--)inv[i]=1ll*inv[i+1]*(i+1)%mod;
    	for(RG int i=0;i<=lim;i++)
    		f[i]=1ll*C(m,i)*C(n,i*s)%mod*Fac[i*s]%mod*qm(qm(Fac[s],i),mod-2)%mod*qm(m-i,n-i*s)%mod;
    	solve(0,lim);
    	int ans=0;
    	for(RG int i=0;i<=lim;i++)ans=(ans+1ll*f[i]*w[i])%mod;
    	cout<<ans<<endl;
    	return 0;
    }
    
    
  • 相关阅读:
    CodeForces-786B Legacy (线段树优化建图,单源最短路)
    CodeForces-528C Data Center Drama
    CodeForces-723E One-Way Reform
    2-SAT入门
    POJ-3683 Priest John's Busiest Day (2-SAT 求任意可行方案)
    转载: 8天学通MongoDB——第一天 基础入门
    C# 非EF注册登录与EF注册登录
    Asp.Net入门(三)
    非EF分页
    sql语句错误大集合
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8974076.html
Copyright © 2020-2023  润新知