P4491 [HAOI2018]染色 容斥+NTT
$ \color{#0066ff}{ 题目描述 }$
为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度为 \(N\) 的序列, 每个位置都可以被染成 \(M\) 种颜色中的某一种.
然而小 C 只关心序列的 \(N\) 个位置中出现次数恰好为 \(S\) 的颜色种数, 如果恰 好出现了 \(S\) 次的颜色有 \(K\) 种, 则小 C 会产生 \(W_k\) 的愉悦度.
小 C 希望知道对于所有可能的染色方案, 他能获得的愉悦度的和对 \(1004535809\) 取模的结果是多少.
\(\color{#0066ff}{输入格式}\)
从标准输入读入数据. 第一行三个整数 \(N, M, S\).
接下来一行 \(M + 1\) 个整数, 第 \(i\) 个数表示 \(W_{i-1}\) .
\(\color{#0066ff}{输出格式}\)
输出到标准输出中. 输出一个整数表示答案.
\(\color{#0066ff}{输入样例}\)
8 8 3
3999 8477 9694 8454 3308 8961 3018 2255 4910
55 96 4
396135414 150956526 115846323 684016411 478047433 741809293 841489850 30757425 354718 455244385 67265783 601148661 653297520 159551113 659259694 422602824 890944094 515558436 708977878 859628263 674258521 366153708 146971849 6161187 658301233 461136214 471709361 18786219 349277110 525215286 508995440 640141358 994347874 337617068 743448773 691546444 504640221 401810440 113565512 194628996 99765846 419008498 110931344 659189735 171012254 255189228 896007913 104632201 451664101 178069999 952991431 840513981 647057140 692809264 931718019 30010246 380306874 368517911 154597143 770763865 497641686 772741050 919136255 321190494 134863734 372165464 743950576 11194552 760810101 386902866 928594467 936096033 784108853 271133783 330481696 61402412 432546315 837809841 492881572 200968716 472860533 777800538 858285842 716767711 483244349 497540302 436003214 827152949 390815935 567741247 468900425 37709000 257282045 362991016 500424354 943931245 116395951
\(\color{#0066ff}{输出样例}\)
524070430
231524284
\(\color{#0066ff}{数据范围与提示}\)
特殊性质: \(\forall 1 \le i \le m, W_i = 0\)
对于 \(100\%\) 的数据, 满足 \(0 \le W_i < 1004535809\)

\(\color{#0066ff}{题解}\)
我们发现,如果钦定k种颜色出现S次,然后剩下位置的颜色选择肯定是m-k这些颜色,但是可能还会有颜色出现S次,我们并不能很容易的计算,于是考虑容斥
我们记一个\(f[i]\)表示出现S次的颜色\(\ge i\)种的方案数,这样设状态就可以不用管刚刚的问题了
然后我们考虑f的计算
首先,钦定i种颜色,组合数\(C_m^i\),每种出现了S次,于是剩下的位置的个数就是\(n-iS\)
剩下的位置我们肯定是颜色随便选,注意不能选钦定的!所以方案显然是\((m-i)^{n-iS}\)
注意还有一部分贡献,就是颜色的位置!于是我们直接可重集排列一下,就是\(\frac{n!}{(S!)^i*(n-iS)!}\)
于是,我们f的计算方式就出来了\(f[i] = C_m^i*(m-i)^{n-iS}*\frac{n!}{(S!)^i*(n-iS)!}\)
然后我们计算答案,设\(ans[i]\)为出现S次颜色恰好i种的方案数,就是用f容斥一下
\(\begin{aligned}ans[i]=\sum_{j=i}^m(-1)^{j-i}*C_j^i*f[j]\end{aligned}\)
实际上并不用到m,可以发现,有贡献的最多同时存在的颜色种类数是\(min\{m, \frac n S\}\)
然后拆开组合数\(\begin{aligned}ans[i]=\sum_{j=i}^m(-1)^{j-i}*\frac{j!}{i!*(j-i)!}*f[j]\end{aligned}\)
然后稍微动一下,大致类似的放在一起\(\begin{aligned}ans[i]=\frac{1}{i!}\sum_{j=i}^m\frac{(-1)^{j-i}}{(j-i)!}*j!*f[j]\end{aligned}\)
显然这是个卷积的形式,直接翻转一下
\(\begin{aligned}ans[i]=\frac{1}{i!}\sum_{j=i}^m\frac{(-1)^{m-j+i+1}}{(m-j+i+1)!}*j!*f[j]\end{aligned}\)
然后NTT就行了。。
#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int mod = 1004535809;
const int maxn = 1e7 + 100;
LL ksm(LL x, LL y) {
LL re = 1LL;
while(y) {
if(y & 1) re = re * x % mod;
x = x * x % mod;
y >>= 1;
}
return re;
}
int len, r[maxn];
using std::vector;
void FNTT(vector<int> &A, int flag) {
A.resize(len);
for(int i = 0; i < len; i++) if(i < r[i]) std::swap(A[i], A[r[i]]);
for(int l = 1; l < len; l <<= 1) {
int w0 = ksm(3, (mod - 1) / (l << 1));
for(int i = 0; i < len; i += (l << 1)) {
int w = 1, a0 = i, a1 = i + l;
for(int k = 0; k < l; k++, a0++, a1++, w = 1LL * w * w0 % mod) {
int tmp = 1LL * A[a1] * w % mod;
A[a1] = ((A[a0] - tmp) % mod + mod) % mod;
A[a0] = (A[a0] + tmp) % mod;
}
}
}
if(!(~flag)) {
int inv = ksm(len, mod - 2);
std::reverse(A.begin() + 1, A.end());
for(int i = 0; i < len; i++) A[i] = 1LL * A[i] * inv % mod;
}
}
vector<int> operator * (vector<int> A, vector<int> B) {
int tot = A.size() + B.size() - 1;
for(len = 1; len <= tot; len <<= 1);
for(int i = 0; i < len; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) * (len >> 1));
FNTT(A, 1), FNTT(B, 1);
vector<int> C;
for(int i = 0; i < len; i++) C.push_back(1LL * A[i] * B[i] % mod);
FNTT(C, -1);
C.resize(tot);
return C;
}
int n, m, fac[maxn], inv[maxn], S, w[maxn];
int C(int x, int y) { return 1LL * fac[x] * inv[y] % mod * inv[x - y] % mod; }
void predoit() {
fac[0] = 1;
for(int i = 1; i < maxn; i++) fac[i] = 1LL * fac[i - 1] * i % mod;
inv[maxn - 1] = ksm(fac[maxn - 1], mod - 2);
for(int i = maxn - 2; i >= 0; i--) inv[i] = 1LL * inv[i + 1] * (i + 1) % mod;
}
int main() {
n = in(), m = in(), S = in();
predoit();
for(int i = 0; i <= m; i++) w[i] = in();
int limit = std::min(m, n / S);
vector<int> A, B;
for(int i = 0; i <= limit; i++) {
A.push_back(1LL * C(m, i) * ksm(m - i, n - i * S) % mod * fac[n] % mod * ksm(inv[S], i) % mod * inv[n - i * S] % mod * fac[i] % mod);
B.push_back((limit - i) & 1? mod - inv[limit - i] : inv[limit - i]);
}
A = A * B;
int now = 0;
for(int i = 0; i <= limit; i++) (now += 1LL * w[i] * A[i + limit] % mod * inv[i] % mod) %= mod;
printf("%d\n", now);
return 0;
}
P4491 [HAOI2018]染色 容斥+NTT的更多相关文章
- 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次的颜色,那么后面式子就会难 ...
- P4491 [HAOI2018]染色 广义容斥 NTT 生成函数
LINK:染色 算是比较常规的广义容斥. 算恰好k个 可以直接转成至少k个. 至少k个非常的好求 直接生成函数. 设\(g_k\)表示至少有k个颜色是满足的 那么有 \(g_k=C(m,k)\frac ...
- BZOJ5306 [HAOI2018]染色 【组合数 + 容斥 + NTT】
题目 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度为 \(N\) 的序列, 每个位置都可以被染成 \(M\) 种颜色中的某一种. 然而小 C 只 ...
- [HAOI2018]染色(容斥+NTT)
补充一篇详细得不能再详细的题解,比如让我自己看懂. 可能与前面的题解有些相同,我想补充一下自己的想法. 显然,最多 \(K\) 最大为 \(N=min(\lfloor \frac nS\rfloor, ...
- HAOI 2018 染色(容斥+NTT)
题意 https://loj.ac/problem/2527 思路 设 \(f(k)\) 为强制选择 \(k\) 个颜色出现 \(s\) 种,其余任取的方案数. 则有 \[ f(k)={m\choos ...
- [洛谷P4491] [HAOI2018]染色
洛谷题目链接:[HAOI2018]染色 题目背景 HAOI2018 Round2 第二题 题目描述 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度 ...
- luogu P4491 [HAOI2018]染色
传送门 这一类题都要考虑推式子 首先推出题目要求的式子,枚举正好有\(s\)个颜色的种类(范围\([0,p=min(\lfloor\frac{n}{s}\rfloor,m)]\)),然后对于后面的颜色 ...
- BZOJ5306 HAOI2018染色(容斥原理+NTT)
容易想到枚举恰好出现S次的颜色有几种.如果固定至少有i种恰好出现S次,那么方案数是C(M,i)·C(N,i*S)·(M-i)N-i*S·(i*S)!/(S!)i,设为f(i). 于是考虑容斥,可得恰好 ...
随机推荐
- 混合开发Js bridge新秀-DSBridge iOS篇
这个DSBridge 和我之前开发做的混合开发 用的方式 很相似,所以觉得很是不错,推荐给你大家. DSBridge-IOS:https://github.com/wendux/DSBridge-IO ...
- 494. Target Sum 添加标点符号求和
[抄题]: You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have ...
- Tftp上传、下载
上传 tftp -g -r filename serverip 下载 tftp -p -l filename serverip
- Python下Pip的安装【get-pip】
1.下载 下载https://bootstrap.pypa.io/get-pip.py 如果不能下载,可下载:http://files.cnblogs.com/files/zhangzhiming/g ...
- python算法 - 快速寻找满足条件的两个数-乾颐堂
题目前提是一定存在这样两个数 解法一就不写了...一般想不到吧 一开始想到的是解法二最后的用hash表 (其实是想到创建一个跟target一样大的数组啦..存在就写入index,但是要全部找出,那得二 ...
- 一张图让你看懂HDMI针脚定义
一张图让你看懂HDMI针脚定义 摘自:http://www.hdmiaoc.com/cjwt-175.html 什么是HDMI线,HDMI插头的每根PIN脚是什么意思? 大部分使用HDMI标准的研发及 ...
- 树状数组 - 2352 Stars
题目地址: http://poj.org/problem?id=2352 分析: - 题意分析: 有n个星星, 它的左下方(x和y不超过它)的星星的数目就是它的level, 分别计算level 为 ...
- windows server2012如何开启mysql远程登录
开发的首要任务就是要搭建起自己的服务器,下面主要是我这搭建记录下 我的各种环境 服务器为Windows server2012 安装的MySQL数据的版本是5.6.10 ,64位.当然了版本对于安装没 ...
- sqlplus 简单的几个查询语句
sqlplus 是用来和oracle进行交互的工具,可以在电脑端使用,也可以在服务器使用 常用命令 show 显示SQL Plus中的信息 connect 先无条件断 ...
- 盒子模型 以及CSS的box-sizing属性。
盒子模型有两种 一种是 内容盒子模型 一种是边框盒子模型. 内容盒子模型(标准盒子模型)由width和height中指定的元素的尺寸不包括内边距和边框 仅是指的内容的实际尺寸: 网上搜索了两张配图不错 ...