P4491 [HAOI2018]染色
题目链接:洛谷
题目大意:$n$个位置染$m$种颜色,如果出现次数恰为$S$次的颜色有$k$种,则对答案有$W_k$的贡献,求所有染色方案的答案之和$\bmod 1004535809$。
数据范围:$n\leq 10^7,m\leq 10^5,S\leq 150,0\leq W_i\leq 1004535808$
首先是要推式子的。
首先我们知道,出现次数恰为$S$次的至多$up=\min(m,\frac{n}{S})$种。
设恰好出现$S$次的颜色至少$i$种,则
$$f_i=C_m^i*\frac{n!}{(S!)^i(n-iS)!}*(m-i)^{n-iS}$$
这三项分别是选$i$种颜色,对现在这$i+1$种颜色(选定的$i$种和未染色的)做可重集排列,对剩下的$n-iS$个位置任意染色。
然后用容斥原理就可以得出,恰好出现$S$次的颜色正好$i$种的方案数
$$ans_i=\sum_{j=i}^{up}(-1)^{j-i}C_j^if_j$$
所以
$$\frac{ans_i}{i!}=\sum_{j=i}^{up}\frac{(-1)^{j-i}}{(j-i)!}*\frac{f_j}{j!}$$
如果你不知道如何做,把第一个数组先反转再向右平移$up$位,再把计算后的$ans_i$左移$up$位就可以了。
#include<cstdio>
#include<algorithm>
#define Rint register int
using namespace std;
typedef long long LL;
const int N = , G = , Gi = , mod = ;
int n, m, s, up, W[N], fac[], inv[], f[N], g[N], ans;
inline int kasumi(int a, int b){
int res = ;
while(b){
if(b & ) res = (LL) res * a % mod;
a = (LL) a * a % mod;
b >>= ;
}
return res;
}
inline void init(){
fac[] = ;
for(Rint i = ;i <= ;i ++) fac[i] = (LL) i * fac[i - ] % mod;
inv[] = inv[] = ;
for(Rint i = ;i <= ;i ++) inv[i] = (LL) inv[mod % i] * (mod - mod / i) % mod;
for(Rint i = ;i <= ;i ++) inv[i] = (LL) inv[i] * inv[i - ] % mod;
}
inline int C(int n, int m){
if(n < m) return ;
return (LL) fac[n] * inv[m] % mod * inv[n - m] % mod;
}
int rev[N];
inline void NTT(int *A, int limit, int type){
for(Rint i = ;i < limit;i ++)
if(i < rev[i]) swap(A[i], A[rev[i]]);
for(Rint mid = ;mid < limit;mid <<= ){
int Wn = kasumi(type == ? G : Gi, (mod - ) / (mid << ));
for(Rint j = ;j < limit;j += mid << ){
int w = ;
for(Rint k = ;k < mid;k ++, w = (LL) w * Wn % mod){
int x = A[j + k], y = (LL) w * A[j + k + mid] % mod;
A[j + k] = (x + y) % mod;
A[j + k + mid] = (x - y + mod) % mod;
}
}
}
if(type == -){
int inv = kasumi(limit, mod - );
for(Rint i = ;i < limit;i ++) A[i] = (LL) A[i] * inv % mod;
}
}
int main(){
scanf("%d%d%d", &n, &m, &s);
for(Rint i = ;i <= m;i ++) scanf("%d", W + i);
init(); up = min(m, n / s);
for(Rint i = ;i <= up;i ++)
f[i] = (LL) C(m, i) * fac[i] % mod * fac[n] % mod * kasumi(inv[s], i) % mod * inv[n - i * s] % mod * kasumi(m - i, n - i * s) % mod;
for(Rint i = ;i <= up;i ++)
g[i] = ((up - i) & ) ? (mod - inv[up - i]) : inv[up - i];
int limit = , L = -;
while(limit <= (up << )){limit <<= ; ++ L;}
for(Rint i = ;i < limit;i ++)
rev[i] = (rev[i >> ] >> ) | ((i & ) << L);
NTT(f, limit, ); NTT(g, limit, );
for(Rint i = ;i < limit;i ++) f[i] = (LL) f[i] * g[i] % mod;
NTT(f, limit, -);
for(Rint i = ;i <= up;i ++)
ans = (ans + (LL) W[i] * f[up + i] % mod * inv[i] % mod) % mod;
printf("%d\n", ans);
}
luogu4491
P4491 [HAOI2018]染色的更多相关文章
- [洛谷P4491] [HAOI2018]染色
洛谷题目链接:[HAOI2018]染色 题目背景 HAOI2018 Round2 第二题 题目描述 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度 ...
- P4491 [HAOI2018]染色 容斥+NTT
$ \color{#0066ff}{ 题目描述 }$ 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度为 \(N\) 的序列, 每个位置都可以被染成 ...
- P4491 [HAOI2018]染色 广义容斥 NTT 生成函数
LINK:染色 算是比较常规的广义容斥. 算恰好k个 可以直接转成至少k个. 至少k个非常的好求 直接生成函数. 设\(g_k\)表示至少有k个颜色是满足的 那么有 \(g_k=C(m,k)\frac ...
- luogu P4491 [HAOI2018]染色
传送门 这一类题都要考虑推式子 首先推出题目要求的式子,枚举正好有\(s\)个颜色的种类(范围\([0,p=min(\lfloor\frac{n}{s}\rfloor,m)]\)),然后对于后面的颜色 ...
- 洛咕 P4491 [HAOI2018]染色
显然颜色数量不会超过\(lim=\min(m,n/S)\) 考虑容斥,计算恰好出现了\(S\)次的颜色有至少\(i\)种的方案数\(f[i]\),钦定\(i\)种颜色正好放\(S\)种 有\(m\)种 ...
- [BZOJ5306] [HAOI2018]染色(容斥原理+NTT)
[BZOJ5306] [HAOI2018]染色(容斥原理+NTT) 题面 一个长度为 n的序列, 每个位置都可以被染成 m种颜色中的某一种. 如果n个位置中恰好出现了 S次的颜色有 K种, 则小 C ...
- BZOJ 5306 [HAOI2018] 染色
BZOJ 5306 [HAOI2018] 染色 首先,求出$N$个位置,出现次数恰好为$S$的颜色至少有$K$种. 方案数显然为$a_i=\frac{n!\times (m-i)^{m-i\times ...
- 【BZOJ5306】 [Haoi2018]染色
BZOJ5306 [Haoi2018]染色 Solution xzz的博客 代码实现 #include<stdio.h> #include<stdlib.h> #include ...
- 【LG4491】[HAOI2018]染色
[LG4491][HAOI2018]染色 题面 洛谷 题解 颜色的数量不超过\(lim=min(m,\frac nS)\) 考虑容斥,计算恰好出现\(S\)次的颜色至少\(i\)种的方案数\(f[i] ...
随机推荐
- NLog使用
NLog的配置文件,文件上面有详细的备注,注意这个配置文件一定要放在NLog.dll的文件夹里 <?xml version="1.0" encoding="utf- ...
- spring mvc中获取请求URL
String baseUrl=request.getScheme()+"://"+request.getServerName()+":"+request.get ...
- R语言使用RMySQL连接及读写Mysql数据库
简单说下安装过程,一般不会有问题,重点是RMySQL的使用方式. 系统环境说明 Redhat系统:Linux 460-42.6.32-431.29.2.el6.x86_64 系统编码:LANG=zh_ ...
- 学习Mysql过程中拓展的其他技术栈:Docker入门介绍
一.Docker的介绍和安装 1. Docker是什么 百度百科的介绍: Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linu ...
- 学习Mysql过程中拓展的其他技术栈:设置linux虚拟机的固定ip和克隆linux虚拟机
一.设置linux虚拟机的固定ip 1. 安装好虚拟机后在菜单栏选择编辑→ 虚拟网络编辑器,打开虚拟网络编辑器对话框,选择Vmnet8 Net网络连接方式,随意设置子网IP,点击NAT设置页面,查看子 ...
- [Artoolkit] Marker of nftSimple
重点看:markers.dat 的解析原理 1. int main(int argc, char** argv) { ]; const char *cparam_name = "Data2/ ...
- Linux Platform驱动模型(一) _设备信息
我在Linux字符设备驱动框架一文中简单介绍了Linux字符设备编程模型,在那个模型中,只要应用程序open()了相应的设备文件,就可以使用ioctl通过驱动程序来控制我们的硬件,这种模型直观,但是从 ...
- angular 4 和django 1.11.1 前后端交互 总结
首先 angular4 和django 1.11.1交互 有跨域问题 所以先关闭cors 和csrf验证 一.解决跨域问题 cors github django-cors-headers 1)安装co ...
- python多行代码简化
python中,可以把多行代码简化为一行,把for循环和if条件判断都集中到一行里来写,示例如下: >>> from nltk.corpus import stopwords > ...
- Linux----面试
1:tcp和udp的区别 TCP:是面向连接的流传输控制协议,具有高可靠性,确保传输数据的正确性,有验证重发机制,因此不会出现丢失或乱序. UDP:是无连接的数据报服务,不对数据报进行检查与修改,无须 ...