前置芝士

可重集排列

NTT

前置定义

\[\begin{aligned}\\
f_i=C_m^i\cdot \frac{n!}{(S!)^i(n-iS)!}\cdot (m-i)^{n-iS}\\
ans_i=\sum\limits_{j=i}^lim (-1)^{j-i}C_j^i f_j\\
\end{aligned}\]

理解:\(m\)种颜色选i种恰好出现\(S\)次,可重全排列,剩余块染色,不过这样有可能会出现剩余块种有恰好出现\(S\)次的情况,所以容斥一下

\(C_j^i\):\(f_j\)里一定包含着\(f_i\),要减掉,同时有可能减掉了在原本\(j+1..\)的东西

推式

\[\begin{aligned}\\
ans_i=\sum\limits_{j=i}^{lim} (-1)^{j-i}\frac{j!}{i!(j-i)!}f_j\\
ans_i\cdot i!=\sum\limits_{j=i}^{lim}(\frac{(-1)^{j-i}}{(j-i)!})\cdot (f_j\cdot j!)\\
\end{aligned}\]

设生产函数\(G,F\)分别对应\((\frac{(-1)^{j-i}}{(j-i)!}),(f_j\cdot j!)\),再把\(F\)翻转一下:

\[\begin{aligned}\\
ans_i\cdot i!&=\sum\limits_{j=i}^{lim}G_{j-i}\cdot F_{lim-j}\\
H&=G*F\\
ans_i\cdot i!&=H_{lim-i}\\
\end{aligned}\]

Code

上\(NTT\)模板就行

#include<bits/stdc++.h>
typedef long long LL;
const LL mod=1004535809,gg=3,maxn=1e7+9;
inline LL Read(){
LL x(0),f(1); char c=getchar();
while(c<'0' || c>'9'){
if(c=='-') f=-1; c=getchar();
}
while(c>='0' && c<='9'){
x=(x<<3)+(x<<1)+c-'0'; c=getchar();
}
return x*f;
}
inline LL Pow(LL base,LL b){
LL ret(1);
while(b){
if(b&1) ret=ret*base%mod; base=base*base%mod; b>>=1;
}return ret;
}
LL fac[maxn],fav[maxn],r[maxn];
inline LL Get_c(int n,int m){
return fac[n]*fav[m]%mod*fav[n-m]%mod;
}
inline LL Fir(LL n){
LL limit(1),len(0);
while(limit<(n<<1)){
limit<<=1; ++len;
}
for(int i=0;i<limit;++i) r[i]=(r[i>>1]>>1)|((i&1)<<len-1);
return limit;
}
inline void NTT(LL *a,int n,int type){
for(int i=0;i<n;++i) if(i<r[i]) std::swap(a[i],a[r[i]]);
for(LL mid=1;mid<n;mid<<=1){
LL wn(Pow(gg,(mod-1)/(mid<<1)));
if(type==-1) wn=Pow(wn,mod-2);
for(LL R=mid<<1,j=0;j<n;j+=R){
for(LL k=0,w=1;k<mid;++k,w=w*wn%mod){
LL x(a[j+k]),y(a[j+mid+k]*w%mod);
a[j+k]=(x+y)%mod; a[j+mid+k]=(x-y+mod)%mod;
}
}
}
if(type==-1){
LL ty(Pow(n,mod-2));
for(int i=0;i<n;++i) a[i]=a[i]*ty%mod;
}
}
LL n,m,S,lim,ret;
LL W[maxn],f[maxn],g[maxn],h[maxn],ans[maxn];
int main(){
n=Read(); m=Read(); S=Read();
for(int i=0;i<=m;++i) W[i]=Read();
lim=std::min(m,n/S);
fac[0]=fac[1]=1;
int up(std::max(n,m));
for(int i=2;i<=up;++i)
fac[i]=fac[i-1]*i%mod;
fav[up]=Pow(fac[up],mod-2);
for(int i=up;i>=1;--i)
fav[i-1]=fav[i]*i%mod;
for(int i=0;i<=lim;++i)
f[i]=Get_c(m,i)*fac[n]%mod* Pow(Pow(fac[S],i),mod-2)%mod *fav[n-i*S]%mod *Pow(m-i,n-i*S)%mod *fac[i]%mod;
for(int i=0;i<=(lim>>1);++i)
std::swap(f[i],f[lim-i]);
for(int i=0;i<=lim;++i)
g[i]=(Pow(-1,i)*fav[i]+mod)%mod;
LL limit(Fir(lim+1));
NTT(f,limit,1); NTT(g,limit,1);
for(int i=0;i<limit;++i) h[i]=g[i]*f[i]%mod;
NTT(h,limit,-1); for(int i=0;i<=lim;++i) ans[i]=h[lim-i]*fav[i]%mod;
for(int i=0;i<=lim;++i) ret=(ret+ans[i]*W[i]%mod)%mod;
printf("%lld\n",ret);
return 0;
}

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

  1. 【题解】[HAOI2018]染色(NTT+容斥/二项式反演)

    [题解][HAOI2018]染色(NTT+容斥/二项式反演) 可以直接写出式子: \[ f(x)={m \choose x}n!{(\dfrac 1 {(Sx)!})}^x(m-x)^{n-Sx}\d ...

  2. [BZOJ5306] [HAOI2018]染色(容斥原理+NTT)

    [BZOJ5306] [HAOI2018]染色(容斥原理+NTT) 题面 一个长度为 n的序列, 每个位置都可以被染成 m种颜色中的某一种. 如果n个位置中恰好出现了 S次的颜色有 K种, 则小 C ...

  3. BZOJ 5306 [HAOI2018] 染色

    BZOJ 5306 [HAOI2018] 染色 首先,求出$N$个位置,出现次数恰好为$S$的颜色至少有$K$种. 方案数显然为$a_i=\frac{n!\times (m-i)^{m-i\times ...

  4. 【BZOJ5306】 [Haoi2018]染色

    BZOJ5306 [Haoi2018]染色 Solution xzz的博客 代码实现 #include<stdio.h> #include<stdlib.h> #include ...

  5. [洛谷P4491] [HAOI2018]染色

    洛谷题目链接:[HAOI2018]染色 题目背景 HAOI2018 Round2 第二题 题目描述 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度 ...

  6. 【LG4491】[HAOI2018]染色

    [LG4491][HAOI2018]染色 题面 洛谷 题解 颜色的数量不超过\(lim=min(m,\frac nS)\) 考虑容斥,计算恰好出现\(S\)次的颜色至少\(i\)种的方案数\(f[i] ...

  7. 【BZOJ5306】[HAOI2018]染色(NTT)

    [BZOJ5306]染色(NTT) 题面 BZOJ 洛谷 题解 我们只需要考虑每一个\(W[i]\)的贡献就好了 令\(lim=min(M,\frac{N}{S})\) 那么,开始考虑每一个\(W[i ...

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

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

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

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

随机推荐

  1. Windows7平台下gitblit服务器安装

    在日常开发工作中,我们通常使用版本控制软件管理团队的源代码,常用的SVN.Git.与SVN相比,Git有分支的概念,可以从主分支创建开发分支,在开发分支测试没有问题之后,再合并到主分支上去,从而避免了 ...

  2. 2019 鹏博士java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.鹏博士等公司offer,岗位是Java后端开发,因为发展原因最终选择去了鹏博士,入职一年时间了,之前面试了很多 ...

  3. vue 数据更新问题

    在uni-app构建选项卡时,方法中改变的数组数据 无法更新v-if中的布尔值 在函数中打印出来是修改成功了,但在页面中并没有进行响应 布局如下: <swiper :current=" ...

  4. 珠宝juelrye宝石

    juelrye n.珠宝 late 14c., juelrye "precious ornaments, jewel juelrye (uncountable) Adornment with ...

  5. SpringCloud之服务注册与发现Eureka+客户端Feign

    前言 SpringCloud 是微服务中的翘楚,最佳的落地方案. Eureka 作为注册中心,是 SpringCloud 体系中最重要最核心的组件之一. Feign 使用接口加注解的方式调用服务,配合 ...

  6. android 各个存储路径及获取方法总结

    最长用到的就这三个位置 /data/data/包名/ /sdcard/Android/data/包名/ /sdcard/xxx 前两个是应用内部存储, 会随着app的卸载而自动删除, sdcard中其 ...

  7. Linux kernel启动选项(参数)(转)

    Linux kernel启动选项(参数)  转载链接https://www.cnblogs.com/linuxbo/p/4286227.html 在Linux中,给kernel传递参数以控制其行为总共 ...

  8. golang并发基础

    1. go协程(go routine) go原生支持并发:goroutine和channel. go协程是与其他函数或方法一起并发运行的函数和方法.go协程可以看作是轻量级线程. 调用函数或者方法时, ...

  9. 图森未来一道笔试题-迷宫难题【BFS找S->E的最短步数】

    时间限制:3秒 空间限制:262144K 图森未来的自动驾驶小卡车今天被派到了一个陌生的迷宫内部运输一些货物. 工程师小图已经提前拿到了这个迷宫的地图,地图是一个n*m的字符矩阵,上面包含四种不同的字 ...

  10. 微信支付之获取openid

    一.准备工具 不管开发什么,官方的文档应该是第一个想到的这里把官方文档贴出来:微信网页授权文档除此之外,我们还需要一个内网穿透的工具在开发环境下让微信能访问到我们的域名.我使用的是natapp.此类工 ...