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

  于是考虑容斥,可得恰好i种的答案为Σ(-1)j-iC(j,i)·f(j) (j=i~min(M,⌊N/S⌋))。因为容斥是一个枚举子集的过程,在算至少i种的方案时,f(j)被计入了C(j,i)次。

  f显然可以通过预处理阶乘及其逆元线性地算出来。考虑怎么快速算后一部分。注意到模数,NTT没跑了。拆开组合数,可以发现是与j-i有关的式子和与j有关的式子相乘,那么把其中一个翻转一下就是卷积了。

  容斥好难啊。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define P 1004535809
#define N 10000010
#define M 100010
#define inv3 334845270
int n,m,s,k,t,w[N],f[M*],a[M*],fac[N],inv[N],r[M*],ans=;
int ksm(int a,int k)
{
if (k==) return ;
int tmp=ksm(a,k>>);
if (k&) return 1ll*tmp*tmp%P*a%P;
else return 1ll*tmp*tmp%P;
}
int C(int n,int m){return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;}
void DFT(int n,int *a,int p)
{
for (int i=;i<n;i++) if (i<r[i]) swap(a[i],a[r[i]]);
for (int i=;i<=n;i<<=)
{
int wn=ksm(p,(P-)/i);
for (int j=;j<n;j+=i)
{
int w=;
for (int k=j;k<j+(i>>);k++,w=1ll*w*wn%P)
{
int x=a[k],y=1ll*w*a[k+(i>>)]%P;
a[k]=(x+y)%P,a[k+(i>>)]=(x-y+P)%P;
}
}
}
}
void mul(int n,int *a,int *b)
{
DFT(n,a,),DFT(n,b,);
for (int i=;i<n;i++) a[i]=1ll*a[i]*b[i]%P;
DFT(n,a,inv3);
int inv=ksm(n,P-);
for (int i=;i<n;i++) a[i]=1ll*a[i]*inv%P;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj5306.in","r",stdin);
freopen("bzoj5306.out","w",stdout);
const char LL[]="%I64d";
#else
const char LL[]="%lld";
#endif
n=read(),m=read(),s=read(),k=min(m,n/s);
for (int i=;i<=m;i++) w[i]=read();
fac[]=;for (int i=;i<=max(n,m);i++) fac[i]=1ll*fac[i-]*i%P;
inv[]=inv[]=;for (int i=;i<=max(n,m);i++) inv[i]=(P-1ll*(P/i)*inv[P%i]%P)%P;
for (int i=;i<=max(n,m);i++) inv[i]=1ll*inv[i]*inv[i-]%P;
for (int i=;i<=k;i++)
f[i]=1ll*C(m,i)*C(n,i*s)%P*ksm(m-i,n-i*s)%P*fac[i*s]%P*ksm(inv[s],i)%P;
t=;while (t<=k*) t<<=;
for (int i=;i<t;i++) r[i]=(r[i>>]>>)|(i&)*(t>>);
for (int i=;i<=k;i++) f[i]=1ll*f[i]*fac[i]%P;
for (int i=;i<=k;i++) a[i]=1ll*((i&)?P-:)*inv[i]%P;
reverse(a,a+k+);
mul(t,f,a);
for (int i=;i<=k;i++) ans=(ans+1ll*f[i+k]*w[i]%P*inv[i]%P)%P;
cout<<ans;
return ;
}

BZOJ5306 HAOI2018染色(容斥原理+NTT)的更多相关文章

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

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

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

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

  3. [HAOI2018][bzoj5306] 染色 [容斥原理+NTT]

    题面 传送门 思路 这道题的核心在于"恰好有$k$种颜色占了恰好$s$个格子" 这些"恰好",引导我们去思考,怎么求出总的方案数呢? 分开考虑 考虑把恰好有$s ...

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

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

  5. [BZOJ5306][HAOI2018]染色

    bzoj luogu Description 给一个长度为\(n\)的序列染色,每个位置上可以染\(m\)种颜色.如果染色后出现了\(S\)次的颜色有\(k\)种,那么这次染色就可以获得\(w_k\) ...

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

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

  7. 【BZOJ5306】 [Haoi2018]染色

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

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

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

  9. BZOJ 5306 [HAOI2018] 染色

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

随机推荐

  1. 在 Virtual Box 安装 Mac Os 并安装 Qt 开发应用

    导读 由于 Beslyric-for-X 项目开发需要,开始尝试在 Mac Os 下开发 Qt 应用.尝试成功后,记录于此,希望对有类似需求的人有所帮助. 本文以开发 Beslyric-for-X 为 ...

  2. java算法----排序----(3)冒泡排序

    package log; public class Test4 { /** * java算法---冒泡排序 * * @param args */ public static void main(Str ...

  3. tornado学习篇(第二部)

    执行字符串表示的函数,并为该函数提供全局变量 本篇的内容从题目中就可以看出来,就是为之后剖析tornado模板做准备,     #!usr/bin/env python #coding:utf-8 n ...

  4. C# out关键词应用

    C#的out关键词,即是方法内赋值. 返回处理后的结果.打个比喻,有一个宽度的需要按比例缩放.标准宽度为88,如宽度大于这个标准宽度的话,按照0.8进行缩放.如果小于标准宽度,输出的结果没变化. 此时 ...

  5. C#去除字符串中的反斜杠

    如下,可以使用C#的Replace()方法来替换,但有一点需要注意的是backslash(反斜杠)是特殊字符. string s = "[\"aaaaaaaaaaaaaaaaaaa ...

  6. url 传递中文参数乱码问题的终极解决方法。

    估计很多人在做web开发的时候,都会碰到过url传递中文参数,有时候会出现乱码的问题,但有些项目或者环境,又不会有问题.当遇到乱码的时候,上网找了很多解决方案,比如: 页面设置它的编码方式,改成utf ...

  7. Trusted Block Chain Summit(2018.10.09)

    时间:2018.10.09地点:北京金隅喜来登大酒店

  8. 数据库日志——mysql与Oracle的日志

    一.MySQL 在数据同步中用的比较多的是MySQL的binlog 1.bin-log简介 它记录了所有的DDL和DML(除了数据查询语句,select与show不记录)语句,以事件形式记录,还包含语 ...

  9. Ionic下的Jpush消息推送与内容显示

    本文测试Jpush将消息推送给手机端,手机端点击通知栏,即可看到具体的推送内容. 1.极光推送消息设置 设置附加字段: 点击发送,手机端收到消息通知. 2.手机接收到的消息通知 点击之后进入具体的页面 ...

  10. Luogu P1966 火柴排队

    这还是一道比较简单的题目,稍微想一下就可以解决.终于有NOIP难度的题目了 首先我们看那个∑(ai-bi)^2的式子,发现这个的最小值就是排序不等式 所以我们只需要改变第一组火柴的顺序,使它和第二组火 ...