[HAOI2018]染色(容斥+NTT)
补充一篇详细得不能再详细的题解,比如让我自己看懂。
可能与前面的题解有些相同,我想补充一下自己的想法。
显然,最多 \(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)的更多相关文章
- P4491 [HAOI2018]染色 容斥+NTT
$ \color{#0066ff}{ 题目描述 }$ 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度为 \(N\) 的序列, 每个位置都可以被染成 ...
- LOJ2527 HAOI2018 染色 容斥、生成函数、多项式求逆
传送门 调了1h竟然是因为1004535809写成了998244353 "恰好有\(K\)种颜色出现了\(S\)次"的限制似乎并不容易达到,考虑容斥计算. 令\(c_j\)表示强制 ...
- [BZOJ5306][HAOI2018]染色(容斥+FFT)
https://www.cnblogs.com/zhoushuyu/p/9138251.html 注意如果一开始F(i)中内层式子中j枚举的是除前i种颜色之外还有几种出现S次的颜色,那么后面式子就会难 ...
- BZOJ5306 [HAOI2018]染色 【组合数 + 容斥 + NTT】
题目 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度为 \(N\) 的序列, 每个位置都可以被染成 \(M\) 种颜色中的某一种. 然而小 C 只 ...
- P4491 [HAOI2018]染色 广义容斥 NTT 生成函数
LINK:染色 算是比较常规的广义容斥. 算恰好k个 可以直接转成至少k个. 至少k个非常的好求 直接生成函数. 设\(g_k\)表示至少有k个颜色是满足的 那么有 \(g_k=C(m,k)\frac ...
- HAOI 2018 染色(容斥+NTT)
题意 https://loj.ac/problem/2527 思路 设 \(f(k)\) 为强制选择 \(k\) 个颜色出现 \(s\) 种,其余任取的方案数. 则有 \[ f(k)={m\choos ...
- BZOJ5306 HAOI2018染色(容斥原理+NTT)
容易想到枚举恰好出现S次的颜色有几种.如果固定至少有i种恰好出现S次,那么方案数是C(M,i)·C(N,i*S)·(M-i)N-i*S·(i*S)!/(S!)i,设为f(i). 于是考虑容斥,可得恰好 ...
- LOJ#6503.「雅礼集训 2018 Day4」Magic[容斥+NTT+启发式合并]
题意 \(n\) 张卡牌 \(m\) 种颜色,询问有多少种本质不同的序列满足相邻颜色相同的位置数量等于 \(k\). 分析 首先本质不同不好直接处理,可以将同种颜色的卡牌看作是不相同的,求出答案后除以 ...
- Gym 100548F Color 给花染色 容斥+组合数学+逆元 铜牌题
Problem F. ColorDescriptionRecently, Mr. Big recieved n flowers from his fans. He wants to recolor th ...
随机推荐
- SpringBoot获取resource下证书失败
1.第一种失败的情况: 本来使用Spring的上下文容器获取文件,将证书文件放在resource下,编译后获取文件会出现报错 java.security.spec.InvalidKeySpecE ...
- Hibernate validator的一些额外特性
分组验证及分组顺序 如果我们想在新增的情况验证id和name,而修改的情况验证name和password,怎么办? 那么就需要分组了. 首先定义分组接口://分组接口就是两个普通的接口,用于标识,类似 ...
- HXY玩卡片(水题测试2017082401&洛谷2192)
题目链接:HXY玩卡片 很水, 简单讲一下思路. 如果没有0,直接无解,因为不可能是10的倍数. 是9的倍数,则各个数位上的数字和为9的倍数,所以5的数量一定是9的倍数,所以只要尽可能多输出9的倍数个 ...
- MySQL open_files_limit相关设置
背景: 数据库链接不上,报错: root@localhost:/var/log/mysql# mysql -uzjy -p -h192.168.1.111 --default-charact ...
- 别人的Linux私房菜(3)主机规划与磁盘分区
磁盘阵列:RAID.将数个硬盘整合成为在操作系统看来是一个硬盘. Linux对笔记本电脑的支持:https://www.linux-laptop.net/ 几乎所有硬件设备存放于/dev/目录. SC ...
- 2018.11.07 bzoj2751: [HAOI2012]容易题(easy)(组合数学)
传送门 组合数学一眼题. 感觉一直做这种题智商会降低. 利用组合数学的分步计数原理. 只用关心每个数不被限制的取值的总和然后乘起来就可以了. 对于大部分数都不会被限制,总和都是n(n+1)2\frac ...
- IntelliJ IDEA 2017版 spring-boot2.0.2 自动配置Condition
描述: 编译器修改参数 -Dfile.encoding=GBK -Dstr.encoding=GBK Condition位置: 某一个类或注解存在的时候,装配,否则不装配 相关代码: ...
- 基础练习 回形取数 (循环 + Java 输入输出外挂)
基础练习 回形取数 时间限制:1.0s 内存限制:512.0MB 问题描述 回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度.一开始位于矩阵左上角,方 ...
- goole Advance client 离线安装
1.下载插件:Advanced Rest Client 2.最新版的Chrome不支持本地安装插件,所以我们要使能开发者模式 3.把插件后缀名crx改为zip 4.解压,点击‘加载正在开发的扩展程序’ ...
- Arria10中PHY的时钟线结构
发送器时钟网络由发送器PLL到发送器通道,它为发送器提供两种时钟 高速串行时钟——串化器的高速时钟 低速并行时钟——串化器和PCS的低速时钟 在绑定通道模式,串行和并行时钟都是由发送器的PLL提供给发 ...