Luogu 4491 [HAOI2018]染色
BZOJ 5306
考虑计算恰好出现$s$次的颜色有$k$种的方案数。
首先可以设$lim = min(m, \left \lfloor \frac{n}{s} \right \rfloor)$,我们在计算的时候只要算到这个$lim$就可以了。
设$f(k)$表示出现$s$次的颜色至少有$k$种的方案数,则
$$f(k) = \binom{m}{k}\binom{n}{ks}\frac{(ks)!}{(s!)^k}(m - k)^{n - ks}$$
就是先选出$k$个颜色和$ks$个格子放这些颜色,这样子总的方案数是全排列除以限排列,剩下的颜色随便放。
处理一下组合数,整个$f$可以在$O(nlogn)$时间内算出来。
设$g(k)$表示出现$s$次的颜色刚好有$k$种的方案数,考虑到对于$\forall i < j$,$g(j)$在$f(i)$中被计算了$\binom{j}{i}$次,所以有
$$f(k) = \sum_{i = k}^{lim}\binom{i}{k}g(i)$$
直接二项式反演回来,
$$g(k) = \sum_{i = k}^{lim}(-1)^{i - k}\binom{i}{k}f(i)$$
拆开组合数,
$$g(k) = \sum_{i = k}^{lim}(-1)^{i - k}\frac{i!}{k!(i - k)!}f(i) = \frac{1}{k!}\sum_{i = k}^{lim}\frac{(-1)^{i - k}}{(i - k)!}(f(i) * (i!))$$
设$A(i) = f(i) * (i!)$,$B(i) = \frac{(-1)^{i}}{i!}$
$$g(k)* (k!) = \sum_{i = k}^{lim}A(i)B(i - k)$$
咕,并不是卷积。
把$B$翻转,再设$B'(i) = B(lim - i)$
$$g(k)* (k!) = \sum_{i = k}^{lim}A(i)B'(lim + k - i)$$
注意到$A*B'$的第$lim + k$项的系数是$\sum_{i = 0}^{lim + k}A(i)B'(lim + k - i)$,但是需要满足
$$ 0 \leq i \leq lim$$
$$ 0 \leq lim + k - i \leq lim $$
$$k \leq i \leq lim$$
刚好满足。
时间复杂度$O(n + mlogm)$。
Code:
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; typedef long long ll; typedef vector <ll> poly;const int N = 1e7 + 5; const int M = 1e5 + 5;int n, m, s; ll w[M], fac[N], ifac[N], f[M], g[M], sum[M];inline void deb(poly c) {for (int i = 0; i < (int)c.size(); i++)printf("%lld%c", c[i], " \n"[i == (int)c.size() - 1]); }namespace Poly {const int L = 1 << 18;const ll P = 1004535809LL;int lim, pos[L];template <typename T>inline void inc(T &x, T y) {x += y;if (x >= P) x -= P;}template <typename T>inline void sub(T &x, T y) {x -= y;if (x < 0) x += P;}inline void reverse(poly &c) {for (int i = 0, j = (int)c.size() - 1; i < j; i++, j--) swap(c[i], c[j]);}inline ll fpow(ll x, ll y) {ll res = 1;for (; y > 0; y >>= 1) {if (y & 1) res = res * x % P;x = x * x % P;}return res;}inline void prework(int len) {int l = 0;for (lim = 1; lim < len; lim <<= 1, ++l);for (int i = 0; i < lim; i++)pos[i] = (pos[i >> 1] >> 1) | ((i & 1) << (l - 1));}inline void ntt(poly &c, int opt) {c.resize(lim, 0);for (int i = 0; i < lim; i++)if (i < pos[i]) swap(c[i], c[pos[i]]);for (int i = 1; i < lim; i <<= 1) {ll wn = fpow(3, (P - 1) / (i << 1));if (opt == -1) wn = fpow(wn, P - 2);for (int len = i << 1, j = 0; j < lim; j += len) {ll w = 1;for (int k = 0; k < i; k++, w = w * wn % P) {ll x = c[j + k], y = c[j + k + i] * w % P;c[j + k] = (x + y) % P, c[j + k + i] = (x - y + P) % P;}}}if (opt == -1) {ll inv = fpow(lim, P - 2);for (int i = 0; i < lim; i++) c[i] = c[i] * inv % P;}}inline poly mul(const poly x, const poly y) {poly u = x, v = y, res;prework(x.size() + y.size() - 1);ntt(u, 1), ntt(v, 1);for (int i = 0; i < lim; i++) res.push_back(u[i] * v[i] % P);ntt(res, -1);res.resize(x.size() + y.size() - 1);return res;}}using Poly :: P; using Poly :: fpow; using Poly :: mul; using Poly :: inc; using Poly :: reverse;template <typename T> inline void read(T &X) {X = 0; char ch = 0; T op = 1;for (; ch > '9'|| ch < '0'; ch = getchar())if (ch == '-') op = -1;for (; ch >= '0' && ch <= '9'; ch = getchar())X = (X << 3) + (X << 1) + ch - 48;X *= op; }inline void prework(int len) {fac[0] = 1;for (int i = 1; i <= len; i++) fac[i] = fac[i - 1] * i % P;ifac[len] = fpow(fac[len], P - 2);for (int i = len - 1; i >= 0; i--) ifac[i] = ifac[i + 1] * (i + 1) % P; }inline ll getC(int x, int y) {return fac[x] * ifac[y] % P * ifac[x - y] % P; }int main() {read(n), read(m), read(s);for (int i = 0; i <= m; i++) read(w[i]);int rep = min(m, n / s);prework(max(n, m));for (int i = 0; i <= rep; i++) f[i] = getC(m, i) * getC(n, i * s) % P * fac[i * s] % P * fpow(ifac[s], i) % P * fpow(m - i, n - i * s) % P;/* for (int i = 0; i <= rep; i++)printf("%lld%c", f[i], " \n"[i == rep]); */poly a, b;a.resize(rep + 1, 0), b.resize(rep + 1, 0);for (int i = 0; i < rep + 1; i++) {a[i] = f[i] * fac[i] % P;b[i] = ifac[i];if (i & 1) b[i] = (P - b[i]) % P;} reverse(b);// deb(a), deb(b); poly c = mul(a, b);// deb(c);/* for (int i = rep; i >= 0; i--) {sum[i] = sum[i + 1];inc(sum[i], c[i]);} for (int i = 0; i <= rep; i++)printf("%lld%c", sum[i], " \n"[i == rep]); */ ll ans = 0;for (int i = 0; i <= rep; i++) {g[i] = ifac[i] * c[rep + i] % P;inc(ans, w[i] * g[i] % P);}printf("%lld\n", ans);return 0; }
View Code
转载于:https://www.cnblogs.com/CzxingcHen/p/10290551.html
Luogu 4491 [HAOI2018]染色相关推荐
- [Luogu 2486] SDOI2011 染色
[Luogu 2486] SDOI2011 染色 树剖水题,线段树维护. 详细题解不写了. 我只想说我写的线段树又变漂亮了qwq #include <algorithm> #include ...
- P4491 [HAOI2018]染色
反思 二项式反演的板子,但是还要加上一个NTT,就变得恶心人了 我NTT写挂调了好长时间... 注意 NTT应该这么写 int tmp=pow((opt)?invG:G,(MOD-1)/i); 而不这 ...
- [HAOI2018]染色
题解 我竟然能自己想出来计数题 容斥+NTT 首先一看到题目让求恰好出现\(S\)次的颜色有恰好\(K\)种就想到容斥 如果容斥每种颜色出现次数的话并不好计数 那么考虑容斥恰好出现\(S\)次的颜色有 ...
- HAOI2018 染色
传送门 一道非常好的容斥+NTT,对我这样的菜鸡难度稍高. 符合要求的颜色最多有\(lim = min(m,\lfloor\frac{n}{S}\rfloor)\)种. 首先,考虑恰好出现S次不是很容 ...
- [HAOI2018] 染色(二项式反演+NTT)
洛谷链接 显然颜色数量不会超过 lim=min(m,ns)\lim=\min(m,\frac ns)lim=min(m,sn) fi:f_i:fi: 至少有 iii 种颜色恰好出现了 sss ...
- PKUWC2019游记
PKUWC2019游记 \(Day\) 很久之前 听说 \(440\) 能去 \(PKUWC\),惊喜啊!其实就是为期末考爆炸找个借口 最近感觉学了不少东西.虽然 \(PKUWC\) 的题目以组合和数 ...
- Luogu P3177 [HAOI2015] 树上染色(树上背包)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Luogu P3177 [HAOI2015] 树上染色 有一棵点数为 NNN 的树,树边有边权.给你一 ...
- 「HAOI2018」染色 解题报告
「HAOI2018」染色 是个套路题.. 考虑容斥 则恰好为\(k\)个颜色恰好为\(c\)次的贡献为 \[ \binom{m}{k}\sum_{i\ge k}(-1)^{i-k}\binom{m-k ...
- 【树链剖分】染色(luogu 2486/金牌导航 树链剖分-3)
正题 luogu 2486 金牌导航 树链剖分-3 题目大意 给你一棵树,让你进行以下操作: 1.把一条路径染上一个颜色 2.查询一条路径上有多少个颜色段 解题思路 用树链剖分把问题转化为链上问题 然 ...
最新文章
- 鸿蒙开发者自学,【5月21日鸿蒙公开课】自学鸿蒙 当代大学生的进阶之路
- 射影几何3:拓广平面
- (转)探究 TCP 一次数据包最大负载,上限真的是 65495 byte 吗
- 速度收藏!600页阿里技术全景图曝光,程序员看完都沸腾了
- IDEA配置git环境
- java aspose重叠_Aspose.Words - 在特定位置合并两个文档
- 改变WCF service location的 hostName
- yarn当中各个主要组件的作用及调度器
- .htaccess文件玩转Rewrite
- android view 画文字,【Android自定义View】绘图之文字篇(三)
- 【leetcode刷题】[简单]427. 建立四叉树(construct quad tree)-java
- ipv4和计算机地址是什么意思,ipv6是什么意思?我们怎么查看电脑iPv6地址
- UA用Mode-Driven的使用笔记
- Win10系统更新完之后,电脑短时间内自动睡眠问题:解决.
- opencv:图像的读取和显示
- ASP一个小型搜索引擎的设计与实现
- PostgreSQL 别名
- Chapter7 循环神经网络-2
- iMindMap Android中字体格式该怎么进行修改
- 15 PyAutoGUI 键盘控制函数(2)
热门文章
- 高效!Anchor DETR:旷视提出一种基于Transformer的目标检测神器!
- 李沐分享斯坦福2021秋季新课:实用机器学习
- 深度学习三(PyTorch物体检测实战)
- 大数据分析实战-信用卡欺诈检测
- python字符串只留数字_Python数字和字符串(5/30)
- java 的进程_windows 启动停止 java进程
- webassembly类型_WebAssembly 现状与实战
- Java 面试之线程与锁
- elementui带输入建议查询_elementUi简单实现搜索提词功能
- python的repl模式_如何更改sublimeREPL默认python版本