补充一篇详细得不能再详细的题解,比如让我自己看懂。

可能与前面的题解有些相同,我想补充一下自己的想法。

显然,最多 \(K\) 最大为 \(N=min(\lfloor \frac nS\rfloor,m)\)

首先,我们看到出现 \(S\) 次的颜色恰好 \(K\) 种的话,我们就可以考虑容斥,将其化为出现 \(S\) 次的颜色至少 \(K\) 种的方案数 \(f[K]\)

那么先选定在 \(m\) 中颜色中选定 \(i\) 种颜色,有 \(C_m^i\) 种

选定在 \(n\) 个位置中选定 \(iS\) 个位置,有 \(C_n^{iS}\) 种

但是 \(iS\) 个位置中随机排列的话,因为颜色相同交换算一种,所以有 \(\frac {iS!}{(S!)^i}\) 种

其他位置可以乱选,剩下 \(m-i\) 中颜色,\(n-iS\) 个位置,有 \((m-i)^{n-iS}\) 种

那么乘法原理,\(f[i]=C_m^iC_n^{iS}\frac {iS!}{(S!)^i}(m-i)^{n-iS}\)

现在定义 \(ans[i]\) 为出现 \(S\) 次颜色恰好 \(K\) 种的方案数,开始容斥。首先想到容斥系数 \((-1)^{j-i}\)

然后在 \(j\) 种颜色中 \(i\) 种颜色的方案数被算了 \(C_j^i\) 次

那么可以推出:

\(ans[i]=\sum_{j=i}^{N}(-1)^{j-i}C_j^if[j]\)

\(ans[i]=\sum_{j=i}^{N}(-1)^{j-i}\frac {j!}{i!(j-i)!}f[j]\)

\(ans[i]\times i!=\sum_{j=i}^{N}(-1)^{j-i}\frac {1}{(j-i)!}f[j]\times j!\)

定义 \(F(x)=\frac {(-1)^i}{i!}\ x^i,G(x)=f[i]\times i!\ x^i\)

但是这样还不能卷积。我们将 \(G(x)\) 系数翻转一下,\(ans[i]\times i!=F(x)*G(x)\) 中 \(x^{N-i}\) 项的系数

那么最终 \(Ans=\sum_{i=0}^{N}w[i]\times ans[i]\)。用 \(NTT\) 实现多项式乘法,时间复杂度 \(O(n\log n)\)

\(Code\ Below:\)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=100000+10;
const int maxm=10000000+10;
const int mod=1004535809;
int n,m,s,N,lim,w[maxn],f[maxn],a[maxn<<2],b[maxn<<2],r[maxn<<2],fac[maxm],inv[maxm]; inline int read(){
register int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return (f==1)?x:-x;
} int C(int n,int m){
if(n<m) return 0;
return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;
} int fpow(int a,int b){
int ret=1;
for(;b;b>>=1,a=1ll*a*a%mod)
if(b&1) ret=1ll*ret*a%mod;
return ret;
} void NTT(int *f,int n,int op){
for(int i=0;i<n;i++)
if(i<r[i]) swap(f[i],f[r[i]]);
int buf,tmp,x,y;
for(int len=1;len<n;len<<=1){
tmp=fpow(3,(mod-1)/(len<<1));
if(op==-1) tmp=fpow(tmp,mod-2);
for(int i=0;i<n;i+=len<<1){
buf=1;
for(int j=0;j<len;j++){
x=f[i+j];y=1ll*buf*f[i+j+len]%mod;
f[i+j]=(x+y)%mod;f[i+j+len]=(x-y+mod)%mod;
buf=1ll*buf*tmp%mod;
}
}
}
if(op==1) return ;
int inv=fpow(n,mod-2);
for(int i=0;i<n;i++) f[i]=1ll*f[i]*inv%mod;
} int main()
{
scanf("%d%d%d",&n,&m,&s);N=min(n/s,m);
for(int i=0;i<=m;i++) scanf("%d",&w[i]);
fac[0]=fac[1]=inv[0]=inv[1]=1;
for(int i=2;i<=max(n,m);i++){
fac[i]=1ll*fac[i-1]*i%mod;
inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
}
for(int i=2;i<=max(n,m);i++) inv[i]=1ll*inv[i]*inv[i-1]%mod;
for(int i=0;i<=N;i++) f[i]=1ll*C(m,i)*C(n,i*s)%mod*fac[i*s]%mod*fpow(inv[s],i)%mod*fpow(m-i,n-i*s)%mod;
for(int i=0;i<=N;i++){
a[i]=(((i&1)?-1:1)*inv[i]+mod)%mod;
b[i]=1ll*f[i]*fac[i]%mod;
}
reverse(b,b+N+1);
for(lim=1;lim<=(N<<1);lim<<=1);
for(int i=0;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)?(lim>>1):0);
NTT(a,lim,1);NTT(b,lim,1);
for(int i=0;i<lim;i++) a[i]=1ll*a[i]*b[i]%mod;
NTT(a,lim,-1);
reverse(a,a+N+1);
int ans=0;
for(int i=0;i<=N;i++) ans=(ans+1ll*w[i]*a[i]%mod*inv[i]%mod)%mod;
printf("%d\n",ans);
return 0;
}

[HAOI2018]染色(容斥+NTT)的更多相关文章

  1. P4491 [HAOI2018]染色 容斥+NTT

    $ \color{#0066ff}{ 题目描述 }$ 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度为 \(N\) 的序列, 每个位置都可以被染成 ...

  2. LOJ2527 HAOI2018 染色 容斥、生成函数、多项式求逆

    传送门 调了1h竟然是因为1004535809写成了998244353 "恰好有\(K\)种颜色出现了\(S\)次"的限制似乎并不容易达到,考虑容斥计算. 令\(c_j\)表示强制 ...

  3. [BZOJ5306][HAOI2018]染色(容斥+FFT)

    https://www.cnblogs.com/zhoushuyu/p/9138251.html 注意如果一开始F(i)中内层式子中j枚举的是除前i种颜色之外还有几种出现S次的颜色,那么后面式子就会难 ...

  4. BZOJ5306 [HAOI2018]染色 【组合数 + 容斥 + NTT】

    题目 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度为 \(N\) 的序列, 每个位置都可以被染成 \(M\) 种颜色中的某一种. 然而小 C 只 ...

  5. P4491 [HAOI2018]染色 广义容斥 NTT 生成函数

    LINK:染色 算是比较常规的广义容斥. 算恰好k个 可以直接转成至少k个. 至少k个非常的好求 直接生成函数. 设\(g_k\)表示至少有k个颜色是满足的 那么有 \(g_k=C(m,k)\frac ...

  6. HAOI 2018 染色(容斥+NTT)

    题意 https://loj.ac/problem/2527 思路 设 \(f(k)\) 为强制选择 \(k\) 个颜色出现 \(s\) 种,其余任取的方案数. 则有 \[ f(k)={m\choos ...

  7. BZOJ5306 HAOI2018染色(容斥原理+NTT)

    容易想到枚举恰好出现S次的颜色有几种.如果固定至少有i种恰好出现S次,那么方案数是C(M,i)·C(N,i*S)·(M-i)N-i*S·(i*S)!/(S!)i,设为f(i). 于是考虑容斥,可得恰好 ...

  8. LOJ#6503.「雅礼集训 2018 Day4」Magic[容斥+NTT+启发式合并]

    题意 \(n\) 张卡牌 \(m\) 种颜色,询问有多少种本质不同的序列满足相邻颜色相同的位置数量等于 \(k\). 分析 首先本质不同不好直接处理,可以将同种颜色的卡牌看作是不相同的,求出答案后除以 ...

  9. Gym 100548F Color 给花染色 容斥+组合数学+逆元 铜牌题

    Problem F. ColorDescriptionRecently, Mr. Big recieved n flowers from his fans. He wants to recolor th ...

随机推荐

  1. python上下文管理协议

    所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with __enter__(self):当with开始运行的时候触发此方法的运行 __exit__(self, exc_type, exc_va ...

  2. JQuery中after() append() appendTo()的区别

    首先 after() 是追加在元素外边而append() appendTo()是追加在元素里面. $(selector).after(content) $("span").afte ...

  3. samba服务和nginx服务

    一  samba服务 1 samba的功能:samba是一个网络服务器,是连接linux和windows之间共享文件的. 2 samba服务的启动,停止和重启: (1) 要启动Samba服务,只需用户 ...

  4. bootstrap表格参数说明

    表格参数: 名称 标签 类型 默认 描述 - data-toggle String ‘table’ 不用写 JavaScript 直接启用表格. classes data-classes String ...

  5. Windows下python环境配置

    步骤: 1.安装Python.Sublime Text: 2.打开Sublime Text,在菜单栏点击“Tools”->“Build System”->“New Build System ...

  6. Fastjson和Gson零碎总结

    一:用于测试的类 User类 import lombok.Data; import lombok.experimental.Accessors; /** * @author silentdoer * ...

  7. 学以致用十一-----centos7.2+python3+YouCompleteMe走过的坑

    目的,安装YouCompleteMe 插件 参考的资料 https://blog.csdn.net/zs376957686/article/details/77833953 https://www.c ...

  8. C#重点内容之:委托(delegate)

    为了记忆方便,提取了重点. 委托类似于指针,可以理解为函数指针的升级版,这是理解委托最关键的地方. Action和Func 系统自带的两种委托: Action Func Action型委托要求委托的目 ...

  9. bzoj4873(最大权闭合子图)

    今天学了最大权闭合子图..然后找了这道题,发现完全不会..... 看了题解发现这种有诸如选了一个就一定要选另外的一些的限制又要求最优值的题有的可以转化成最大权闭合子图, 这个题我们首先想到不会选相交的 ...

  10. (树状数组+离散化)lines--hdu --5124

    http://acm.hdu.edu.cn/showproblem.php?pid=5124 lines Time Limit: 5000/2500 MS (Java/Others)    Memor ...