• [HAOI2018]染色


    神仙题

    发现不会容斥,于是自闭

    发现这个叫广义容斥,好神仙啊

    我们先来设

    (g_i)表示至少(i)种颜色出现了恰好(S)次的方案数,(f_i)表示恰好(i)种颜色出现了恰好(i)次的方案数

    我们设(L=min(m,n/S)),表示最多能有多少种颜色恰好出现(S)

    我们显然有

    [g_i=sum_{j=i}^Linom{j}{i}f_j ]

    就是枚举出现次数大于等于(i)的,从(j)中选出(i)

    根据我不会的二项式反演

    [f_i=sum_{j=i}^L(-1)^{j-i}inom{j}{i}g_j ]

    我们要求的就是(sum_{i=0}^Lw_i imes f_i),于是我们需要求出所有的(f_i)

    现在需要求出(g_i)

    首先我们先从(m)种颜色选出(i)种颜色,这里是(inom{m}{i}),我们强制这些颜色出现恰好(S)次,之后对于剩下的(n-i imes S)个位置,我们每个位置都能填剩下的(m-i)种颜色,于是这里是((m-i)^{n-i imes S}),之后对于选出来的(i)种颜色,我们需要让这(i)种颜色,一共(i imes S)个位置排列一下

    这里的是

    [inom{n}{S} imes inom{n-S}{S} imes inom{n-2 imes S}{S}... ]

    就是显然第一种颜色选择(S)个位置,第二种颜色在剩下的(n-S)个位置里选择(S)个位置,以此类推也就是

    [prod_{j=0}^{i-1}inom{n-j imes S}{S} ]

    我们暴力展开这个式子

    [prod_{j=0}^{i-1}inom{n-j imes S}{S} ]

    [=prod_{j=0}^{i-1}frac{(n-j imes S)!}{S!(n-j imes S-S)!} ]

    [=prod_{j=0}^{i-1}frac{prod_{k=n-(j+1) imes S+1}^{n-j imes S}k}{S!}=frac{n!}{(S!)^i(n-i imes S)!} ]

    于是

    [g_i=inom{m}{i} imes (m-i)^{n-i imes S} imes frac{n!}{(S!)^i(n-i imes S)!} ]

    发现我们可以把(g)提前预处理出来啊

    于是我们直接来求(f),照例拆开组合数

    [f_i=sum_{j=i}^L (-1)^{j-i}frac{j!}{i!(j-i)!}g_j ]

    提出(i!)

    [(-1)^if_i imes i!=sum_{j=i}^L(-1)^jj! g_j imes frac{1}{(j-i)!} ]

    我们发现后面长得还不是很像一个卷积的形式,但是已经非常接近了

    我们考虑把(g)反转,发现和阶乘的逆元卷积一下正好得到了(f)的反转

    于是我们直接(NTT)就好了

    代码

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define re register
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    const int maxn=262144+15;
    const int maxN=1e7+5;
    const LL mod=1004535809;
    LL G[2];
    inline int read() {
    	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    int n,m,S,L;
    LL inv[maxN],fac[maxN];
    int len,rev[maxn];
    LL g[maxn],h[maxn],t[maxn],k[maxn];
    inline LL ksm(LL a,int b) {
    	LL S=1;
    	while(b) {if(b&1) S=S*a%mod;b>>=1;a=a*a%mod;}
    	return S;
    }
    inline LL C(int n,int m) {
    	if(m>n) return 0;
    	return fac[n]*inv[m]%mod*inv[n-m]%mod;
    }
    inline void NTT(LL *f,int o) {
        for(re int i=0;i<len;i++) if(i<rev[i]) std::swap(f[i],f[rev[i]]);
        for(re int i=2;i<=len;i<<=1) {
            int ln=i>>1;LL og1=ksm(G[o],(mod-1)/i);
            for(re int l=0;l<len;l+=i) {
                LL t,og=1;
                for(re int x=l;x<l+ln;x++) {
                    t=(og*f[ln+x])%mod;
                    f[ln+x]=(f[x]-t+mod)%mod;
                    f[x]=(f[x]+t)%mod;
                    og=(og*og1)%mod;
                }
            }
        }
        if(!o) return;
        LL inv=ksm(len,mod-2);
        for(re int i=0;i<len;i++) f[i]=(f[i]*inv)%mod;
    }
    int main() {
    	G[0]=3,G[1]=ksm(3,mod-2);
    	n=read(),m=read(),S=read();
    	L=min(m,n/S);len=1;
    	while(len<L+L+2) len<<=1;
    	int T=max(n,m);
    	for(re int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|((i&1)?len>>1:0);
    	fac[0]=1;
    	for(re int i=1;i<=T;i++) fac[i]=(1ll*i*fac[i-1])%mod;
    	inv[T]=ksm(fac[T],mod-2);
    	for(re int i=T-1;i>=0;--i) inv[i]=(1ll*(i+1)*inv[i+1])%mod;
    	for(re int i=0;i<=L;i++) 
    		g[i]=C(m,i)*ksm(m-i,n-i*S)%mod*fac[n]%mod*ksm(inv[S],i)%mod*inv[n-i*S]%mod;
    	for(re int i=0;i<=L;i++) g[i]=g[i]*fac[i]%mod;
    	for(re int i=0;i<=L;i++) {
    		if(i&1) g[i]=(mod-g[i])%mod;
    		k[L-i]=g[i];
    	}
    	for(re int i=0;i<=L;i++) h[i]=inv[i];
    	NTT(k,0),NTT(h,0);
    	for(re int i=0;i<len;i++) k[i]=(k[i]*h[i])%mod;
    	NTT(k,1);
    	for(re int i=0;i<=L;i++) t[i]=k[L-i],t[i]=(t[i]*inv[i])%mod;
    	for(re int i=0;i<=L;i++) if(i&1) t[i]=(mod-t[i])%mod;
    	LL ans=0;
    	for(re int i=0;i<=m;i++) {
    		int x=read();
    		if(i<=L) ans=(ans+1ll*x*t[i]%mod)%mod;
    	} 
    	printf("%d
    ",(int)ans);
    	return 0;
    }
    
  • 相关阅读:
    C#使用CurrentUICulture切换语言
    XmlNode与XmlElement的区别总结
    git 怎样删除远程仓库的最近一次错误提交?
    Kermit,Xmodem,1K-Xmodem,Ymodem,Zmodem传输协议小结
    C#串口通信发送数据
    通过 Chrome 调试运行在 IOS-safari 上的页面
    display:flex不兼容Android、Safari低版本的解决方案 【flex布局】
    jquery获取<div></div>之间的内容.text() 和 .html()区别
    vscode格式化代码无效--可能的解决方法
    git pull出现fatal: unable to access 'https://github.com/XXX/YYY.git'
  • 原文地址:https://www.cnblogs.com/asuldb/p/10630516.html
Copyright © 2020-2023  润新知