题目链接:洛谷

题目大意:$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]染色的更多相关文章

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

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

  2. P4491 [HAOI2018]染色 容斥+NTT

    $ \color{#0066ff}{ 题目描述 }$ 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度为 \(N\) 的序列, 每个位置都可以被染成 ...

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

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

  4. luogu P4491 [HAOI2018]染色

    传送门 这一类题都要考虑推式子 首先推出题目要求的式子,枚举正好有\(s\)个颜色的种类(范围\([0,p=min(\lfloor\frac{n}{s}\rfloor,m)]\)),然后对于后面的颜色 ...

  5. 洛咕 P4491 [HAOI2018]染色

    显然颜色数量不会超过\(lim=\min(m,n/S)\) 考虑容斥,计算恰好出现了\(S\)次的颜色有至少\(i\)种的方案数\(f[i]\),钦定\(i\)种颜色正好放\(S\)种 有\(m\)种 ...

  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. 【LG4491】[HAOI2018]染色

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

随机推荐

  1. 常用curl测试命令

    1.curl 基础用法 2.curl 常用 3.curl 拓展 1.curl基础用法 语法:# curl [option] [url] curl除了用以请求数据,还可以用来上传下载 -A/--user ...

  2. plsql常用方法-转

    在SQLPLUS下,实现中-英字符集转换alter session set nls_language='AMERICAN';alter session set nls_language='SIMPLI ...

  3. db2 索引

    索引:可通过 SYSCAT.INDEXES JOIN SYSCAT.INDEXCOLUSE来查询索引的字段有升序ASC和降序DESC,分别表示为SYSCAT.INDEXES的COLNAMES中索引字段 ...

  4. Error - SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM

    I find using the following works quite well for SQL min/max dates after many DB related errors: Date ...

  5. 0x800f0845 更新1803报错

    Windows 10累积更新KB4056892可能并不兼容AMD处理器,采用AMD Athlon 64 X2处理器的设备至少存在两起报告.

  6. HTML jQuery实现的expend row

    问 题:今天接到个任务,在一个老的系统页面里实现可展开的表格行. 寻找: 1.首先想到了在easyUI里见过的expand row form: 2.但是我们的老系统管理只有jQuery,如果使用eas ...

  7. Linux input子系统编程、分析与模板

    输入设备都有共性:中断驱动+字符IO,基于分层的思想,Linux内核将这些设备的公有的部分提取出来,基于cdev提供接口,设计了输入子系统,所有使用输入子系统构建的设备都使用主设备号13,同时输入子系 ...

  8. 英语语言能力挑战游戏: anagrams & palindromes

    基于英语语言的知名游戏(可以归类为智商挑战题): anagrams anagram定义为一个有着相同的字母的不同的词,例: stop的anagram为:tops, opts, pots, and sp ...

  9. 利用python对微信自动进行消息推送

    from wxpy import * #该库主要是用来模拟与对接微信操作的 import requests from datetime import datetime import time impo ...

  10. JVM源码分析之栈溢出完全解读

    概述 之所以想写这篇文章,其实是因为最近有不少系统出现了栈溢出导致进程crash的问题,并且很隐蔽,根本原因还得借助coredump才能分析出来,于是想从JVM实现的角度来全面分析下栈溢出的这类问题, ...