bzoj

luogu

Description

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

求所有染色方案的收益之和膜\(1004535809\).

sol

整行公式太大了放不下就只能用行内公式了qaq

首先设\(N=\min(m,\lfloor\frac ns\rfloor)\),这是出现了\(S\)次的颜色种数的上界。

设\(F(i)\)表示染色后出现了\(S\)次的颜色有\(i\)中的染色方案数,那么答案就是:

\(Ans=\sum_{i=0}^{N}w_i*F(i)\)

考虑一个对\(F(i)\)的容斥。

\(F(i)=\frac{m!}{i!(m-i)!}\frac{n!}{(S!)^i(n-iS)!}\sum_{j=i}^{N}(-1)^{j-i}\frac{(m-i)!}{(j-i)!(m-j)!}\frac{(n-iS)!}{(S!)^{j-i}(n-jS)!}(m-j)^{n-jS}\)

解释一下:

\(\frac{m!}{i!(m-i)!}\)是从\(m\)中颜色里面选出\(i\)种。

\(\frac{n!}{(S!)^i(n-iS)!}\)是从\(n\)个位置中选出\(iS\)个然后再进行可重排列,也可以理解为在\(n\)个里面选出\(S\)个,再在\(n-S\)个里面选出\(S\)个,在\(n-2S\)个里面选出\(S\)个。。。乘起来就是这个。

接下来就是在剩下的\(m-i\)中颜色中,在\(n-iS\)个位置上随便填,但是随便填的时候可能还会出现某种颜色出现了\(S\)次,所以需要容斥。

\(j\)表示实际上出现了\(S\)次的颜色有\(j\)种,那么就还需要在\(m-i\)中颜色中选出\(j-i\)种,在\(n-iS\)个位置中选出\((j-i)S\)个进行可重排列,然后剩下的随便填,随便填的方案数是\((m-j)^{n-jS}\)。

式子应该不难理解,接下来就是化简了。

\(F(i)=\frac{m!}{i!(m-i)!}\frac{n!}{(S!)^i(n-iS)!}\sum_{j=i}^{N}(-1)^{j-i}\frac{(m-i)!}{(j-i)!(m-j)!}\frac{(n-iS)!}{(S!)^{j-i}(n-jS)!}(m-j)^{n-jS}\\=\frac{m!n!}{i!}\sum_{j=i}^{N}(-1)^{j-i}\frac{1}{(j-i)!(m-j)!}\frac{1}{(S!)^{j}(n-jS)!}(m-j)^{n-jS}\)

发现里面的\(j\)不太好做,于是把\(j\)提到外层。

\(Ans=\sum_{i=0}^{N}w_i*F(i)=\sum_{i=0}^{N}\frac{m!n!w_i}{i!}\sum_{j=i}^{N}(-1)^{j-i}\frac{1}{(j-i)!(m-j)!}\frac{1}{(S!)^{j}(n-jS)!}(m-j)^{n-jS}\\=m!n!\sum_{j=0}^{N}\frac{(m-j)^{n-jS}}{(m-j)!(S!)^{j}(n-jS)!}\sum_{i=0}^{j}\frac{w_i}{i!}\frac{(-1)^{j-i}}{(j-i)!}\)

后面就可以\(NTT\)了,复杂度\(O(N\log_2N)\)

code

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int gi(){
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
const int _ = 1e7+5;
const int mod = 1004535809;
int n,m,s,N,lim,len,jc[_],inv[_],a[_],b[_],rev[_],l,og[_],ans;
int fastpow(int a,int b){
int res=1;
while (b) {if (b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;}
return res;
}
void ntt(int *P,int opt){
for (int i=0;i<len;++i) if (i<rev[i]) swap(P[i],P[rev[i]]);
for (int i=1;i<len;i<<=1){
int W=fastpow(3,(mod-1)/(i<<1));
if (opt==-1) W=fastpow(W,mod-2);
og[0]=1;
for (int j=1;j<i;++j) og[j]=1ll*og[j-1]*W%mod;
for (int p=i<<1,j=0;j<len;j+=p)
for (int k=0;k<i;++k){
int x=P[j+k],y=1ll*og[k]*P[j+k+i]%mod;
P[j+k]=(x+y)%mod,P[j+k+i]=(x-y+mod)%mod;
}
}
if (opt==-1) for (int i=0,Inv=fastpow(len,mod-2);i<len;++i) P[i]=1ll*P[i]*Inv%mod;
}
int main(){
n=gi();m=gi();s=gi();N=min(m,n/s);lim=max(n,max(m,s));
jc[0]=1;
for (int i=1;i<=lim;++i) jc[i]=1ll*jc[i-1]*i%mod;
inv[lim]=fastpow(jc[lim],mod-2);
for (int i=lim;i;--i) inv[i-1]=1ll*inv[i]*i%mod;
for (len=1;len<=(N<<1);len<<=1) ++l;--l;
for (int i=0;i<len;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<l);
for (int i=0;i<=N;++i) a[i]=1ll*gi()*inv[i]%mod;
for (int i=0;i<=N;++i) b[i]=i&1?mod-inv[i]:inv[i];
ntt(a,1);ntt(b,1);
for (int i=0;i<len;++i) a[i]=1ll*a[i]*b[i]%mod;
ntt(a,-1);
for (int i=0;i<=N;++i) (ans+=1ll*fastpow(m-i,n-i*s)*inv[m-i]%mod*fastpow(inv[s],i)%mod*inv[n-i*s]%mod*a[i]%mod)%=mod;
ans=1ll*jc[n]*jc[m]%mod*ans%mod;
printf("%d\n",ans);
return 0;
}

[BZOJ5306][HAOI2018]染色的更多相关文章

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

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

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

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

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

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

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

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

  5. 【BZOJ5306】 [Haoi2018]染色

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

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

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

  7. BZOJ 5306 [HAOI2018] 染色

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

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

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

  9. 【LG4491】[HAOI2018]染色

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

随机推荐

  1. LintCode 394: First Will Win

    LintCode 394: First Will Win 题目描述 有n个硬币排成一条线.两个参赛者轮流从右边依次拿走1或2个硬币,直到没有硬币为止.拿到最后一枚硬币的人获胜. 请判定 第一个玩家 是 ...

  2. 【CODEVS】1033 蚯蚓的游戏问题

    [算法]网络流-最小费用最大流(费用流) [题解]与方格取数2类似 在S后添加辅助点S_,限流k 每条边不能重复走,限流1 #include<cstdio> #include<alg ...

  3. C语言与汇编语言对照分析

    游戏通常会包含各种各样的功能,如战斗系统.UI渲染.经济系统.生产系统等,每个系统又包含各式各样子功能,如伤害判定.施法.使用道具.角色移动.玩家之间交易等等.这些游戏功能在代码实现中往往少不了条件判 ...

  4. Docker微容器Alpine Linux

    Alpine 操作系统是一个面向安全的轻型 Linux 发行版. 它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功 ...

  5. 【Tomcat】 windows下注册tomcat服务以及设置jvm参数

    注册服务: 1 >cd /d D:\Java\tomcat-7.0.57-Css\bin //进入目录 1 >service.bat install  //注册服务,同理删除服务为 rem ...

  6. (2)剑指Offer之二维数组查找和替换空格问题

    一 二维数组查找 题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 问 ...

  7. 一个TCP报文段的数据部分最多为多少个字节,为什么

    IP数据报的最大长度=2^16-1=65535(字节)TCP报文段的数据部分=IP数据报的最大长度-IP数据报的首部-TCP报文段的首部=65535-20-20=65495(字节) 一个tcp报文段的 ...

  8. Linux系统调用、新增系统调用方法【转】

    转自:http://blog.chinaunix.net/uid-25374603-id-3401045.html 说明: 系统调用是内核和应用程序间的接口,应用程序要访问硬件设备和其他操作系统资源, ...

  9. Linux下如何打开img镜像文件

    有些镜像文件为IMG格式,在Linux如何打开呢?例如从微软dreampark下载的Windows Server 2008 R2镜像文件,使用file命令查看: $ file chs_windows_ ...

  10. Python 生成随机数

    import random x = int(input('Enter a number for x: '))  --随机数最小值y = int(input('Enter a number for y: ...