非常明显的摆了一个NTT模数....

题目中求恰好\(k\),那么考虑求至少\(k\)

记\(g(k)\)表示至少\(k\)中颜色出现了恰好\(S\)次

那么,$$g(k) = \binom{M}{k} \frac{N!}{(S!)^k (N-Sk)!} * (M-k)^{N-Sk}$$

根据广义容斥原理,记\(f(i)\)表示恰好\(k\)种颜色出现了恰好\(k\)次

那么,$$f(i) = \sum \limits_{k = i}^M (-1)^{k - i} \binom{k}{i} g(k)$$

化成卷积式

\[f(i) * i! = \sum \limits_{k = i}^M \frac{(-1)^{k - i}}{(k - i)!} k! g(k)
\]

令\(F_i = \frac{(-1)^{i}}{i!}\),\(G_i = i! g(i)\)

记\(H_i\)表示\(f(i) * i\),那么

\[H_i = \sum \limits_{j = i}^M F(k - i) * G(k)
\]

反转下标,有

\[H_{n - i}' = \sum \limits_{i = 0}^{n - i} F(k) * G'(n - i - k)
\]

\(NTT\)即可,复杂度\(O(n \log n)\)


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; #define ri register int
#define rep(io, st, ed) for(ri io = st; io <= ed; io ++) #define gc getchar
inline int read() {
int p = 0, w = 1; char c = gc();
while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
return p * w;
} const int sid = 3e5 + 5;
const int cid = 1e7 + 5;
const int mod = 1004535809; inline int mul(int a, int b) { return 1ll * a * b % mod; }
inline int fp(int a, int k) {
int ret = 1;
for( ; k; k >>= 1, a = mul(a, a))
if(k & 1) ret = mul(ret, a);
return ret;
} int N, M, S, n, lg;
int fac[cid], inv[cid];
int rev[sid], f[sid], g[sid], w[sid], W[sid]; inline int C(int n, int m) {
if(n < m) return 0;
return mul(fac[n], mul(inv[m], inv[n - m]));
} inline void NTT(int *a) {
for(ri i = 0; i < n; i ++)
if(i < rev[i]) swap(a[i], a[rev[i]]);
for(ri i = 1; i < n; i <<= 1)
for(ri j = 0, kj = n / (i << 1); j < n; j += (i << 1))
for(ri k = j, kp = 0; k < i + j; k ++, kp += kj) {
int x = a[k], y = mul(w[kp], a[i + k]);
a[k] = (x + y >= mod) ? x + y - mod : x + y;
a[i + k] = (x - y < 0) ? x - y + mod : x - y;
}
} inline void calc() {
n = 1; lg = 0;
while(n <= M + M) n <<= 1, lg ++;
rep(i, 0, n) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
int g_ = fp(3, (mod - 1) / n);
w[0] = 1;
rep(i, 1, n) w[i] = mul(w[i - 1], g_); int lim = max(N, n);
fac[0] = fac[1] = inv[0] = inv[1] = 1;
rep(i, 2, lim) {
fac[i] = mul(fac[i - 1], i);
inv[i] = mul(inv[mod % i], mod - mod / i);
}
rep(i, 2, lim) inv[i] = mul(inv[i], inv[i - 1]); rep(i, 0, M - 1) f[i] = mul(inv[i], (i & 1) ? mod - 1: 1);
rep(i, 0, M) if(N >= S * i)
g[i] = 1ll*fac[i]*C(M,i)%mod*fac[N]%mod*fp(inv[S],i)%mod*inv[N-S*i]%mod*fp(M-i,N-S*i)%mod;
reverse(g, g + M + 1); NTT(f); NTT(g);
rep(i, 0, n) f[i] = mul(f[i], g[i]);
NTT(f);
int ivn = fp(n, mod - 2);
reverse(f + 1, f + n); reverse(f, f + M + 1);
rep(i, 0, n) f[i] = mul(f[i], mul(ivn, inv[i])); int ans = 0;
rep(i, 0, M) ans = (ans + mul(f[i], W[i])) % mod;
printf("%d\n", ans); } int main() {
N = read(); M = read(); S = read();
rep(i, 0, M) W[i] = read();
calc();
return 0;
}

luoguP4491 [HAOI2018]染色 广义容斥原理 + FFT的更多相关文章

  1. P4491 [HAOI2018]染色 广义容斥 NTT 生成函数

    LINK:染色 算是比较常规的广义容斥. 算恰好k个 可以直接转成至少k个. 至少k个非常的好求 直接生成函数. 设\(g_k\)表示至少有k个颜色是满足的 那么有 \(g_k=C(m,k)\frac ...

  2. Luogu4491 [HAOI2018]染色 【容斥原理】【NTT】

    题目分析: 一开始以为是直接用指数型生成函数,后来发现复杂度不对,想了一下容斥的方法. 对于有$i$种颜色恰好出现$s$次的情况,利用容斥原理得到方案数为 $$\binom{m}{i}\frac{P_ ...

  3. [题解 LuoguP4491 [HAOI2018]染色

    传送门 神仙计数题 Orz 先令\(F[k]\)表示出现次数恰好为\(S\)次的颜色恰好有\(k\)中的方案数,那么 \[Ans=\sum\limits_{i=0}^mW_iF[i]\] 怎么求\(F ...

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

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

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

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

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

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

  7. BZOJ 5306 [HAOI2018] 染色

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

  8. 【BZOJ5306】 [Haoi2018]染色

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

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

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

随机推荐

  1. Servlet笔记1--概述

    JavaEE概述及系统架构分析: (1) JavaEE概述: (2) 系统架构分析:

  2. 【bzoj题解】1012 最大数

    题目描述 现在请求你维护一个数列,要求提供以下两种操作:1.查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2.插入操作.语法:A ...

  3. asp.net 获取音视频时长 的方法

    http://www.evernote.com/l/AHPMEDnEd65A7ot_DbEP4C47QsPDYLhYdYg/ 日志:   1.第一种方法:   调用:shell32.dll ,win7 ...

  4. 『实践』Java Web开发之分页(ajax)

    1.需要用到的jar包.js文件 JSONArray().fromObject()需要的jar包: (1)commons-beanutils-1.8.3.jar (2)commons-collecti ...

  5. mysql高可用架构 -> MHA配置VIP漂移-05

    VIP漂移的两种方式 1)通过keepalived的方式,管理虚拟IP的漂移 2)通过MHA自带脚本方式,管理虚拟IP的漂移 MHA脚本方式 虚拟ip漂移的脚本下载地址 -> wget http ...

  6. Python基础(1):dir(),help()

    Python:3.6.4 开始编写Python程序了...可是,某个模块怎么用呢?模块里的函数怎么用呢?...使用本文介绍的dir().help()两个帮助函数可以 获得绝大部分开发所需要的信息! d ...

  7. git —— 异常1,index.lock

    git提交过程中出现的问题 解决方法:找到 index.lock文件将其删除 一般 index.lock 在.git下面, 有时 .git 是隐藏的,但是无论怎样, 可以通过 everything 找 ...

  8. JS中精选this关键字的指向规律你记住了吗

      1.首先要明确:           谁最终调用函数,this指向谁           this指向的永远只可能是对象!!!!!          this指向谁永远不取决于this写在哪,而取 ...

  9. Windbg在应用层调试漏洞时的应用

    主要记录一些在应用层调试漏洞的技巧,不会写一些基本的命令,只记录比较有用的平时难以想到的调试方法. 1.!address eax 查看对应内存页的属性,如果poc触发异常之后就可以用这个指令看一下触发 ...

  10. SSIS 学习之旅 FTP文件传输-脚本任务

    这一章主要讲解一下用脚本怎么把CSV文件抛送到FTP服务器上 设计:   通过Demon库的Users表数据生成CSV文件.   生成后的CSV文件抛送到FTP指定目录下. 控件的使用这里就不做详细讲 ...