【xsy2479】counting 生成函数+多项式快速幂
题目大意:在字符集大小为$m$的情况下,有多少种构造长度为$n$的字符串$s$的方案,使得$C(s)=k$。其中$C(s)$表示字符串$s$中出现次数最多的字符的出现次数。
对$998244353$取模,$n,m≤5\times 10^4$
如果你考虑去DP,你就lose了。
令$F(x)$表示满足$C(s)≤x$的方案数。
那么最终的答案显然为$F(k)-F(k-1)$。
这一题有一个非常优美的性质:对于每一种字符,允许的最多出现次数都是$k$。
那么,令$G_k(x)=\sum\limits_{i=0}^{k} \frac{1}{i!}x^i$
则有$F(k)=n![x^n]G_k^m(x)$
证明是显然的
写一个多项式快速幂的板子就过了。
- #include<bits/stdc++.h>
- #define M (1<<17)
- #define L long long
- #define MOD 998244353
- #define G 3
- using namespace std;
- L pow_mod(L x,L k){
- L ans=;
- while(k){
- if(k&) ans=ans*x%MOD;
- x=x*x%MOD; k>>=;
- }
- return ans;
- }
- void change(L a[],int n){
- for(int i=,j=;i<n-;i++){
- if(i<j) swap(a[i],a[j]);
- int k=n>>;
- while(j>=k) j-=k,k>>=;
- j+=k;
- }
- }
- void NTT(L a[],int n,int on){
- change(a,n);
- for(int h=;h<=n;h<<=){
- L wn=pow_mod(G,(MOD-)/h);
- for(int j=;j<n;j+=h){
- L w=;
- for(int k=j;k<j+(h>>);k++){
- L u=a[k],t=w*a[k+(h>>)]%MOD;
- a[k]=(u+t)%MOD;
- a[k+(h>>)]=(u-t+MOD)%MOD;
- w=w*wn%MOD;
- }
- }
- }
- if(on==-){
- L inv=pow_mod(n,MOD-);
- for(int i=;i<n;i++) a[i]=a[i]*inv%MOD;
- reverse(a+,a+n);
- }
- }
- void getinv(L a[],L b[],int n){
- if(n==){b[]=pow_mod(a[],MOD-); return;}
- static L c[M],d[M];
- memset(c,,n<<); memset(d,,n<<);
- getinv(a,c,n>>);
- for(int i=;i<n;i++) d[i]=a[i];
- NTT(d,n<<,); NTT(c,n<<,);
- for(int i=;i<(n<<);i++) b[i]=(*c[i]-d[i]*c[i]%MOD*c[i]%MOD+MOD)%MOD;
- NTT(b,n<<,-);
- for(int i=;i<n;i++) b[n+i]=;
- }
- void qiudao(L a[],L b[],int n){
- memset(b,,sizeof(b));
- for(int i=;i<n;i++) b[i-]=i*a[i]%MOD;
- }
- void jifen(L a[],L b[],int n){
- memset(b,,sizeof(b));
- for(int i=;i<n;i++) b[i+]=a[i]*pow_mod(i+,MOD-)%MOD;
- }
- void getln(L a[],L b[],int n){
- static L c[M],d[M];
- memset(c,,n<<); memset(d,,n<<);
- qiudao(a,c,n); getinv(a,d,n);
- NTT(c,n<<,); NTT(d,n<<,);
- for(int i=;i<(n<<);i++) c[i]=c[i]*d[i]%MOD;
- NTT(c,n<<,-);
- jifen(c,b,n);
- }
- void getexp(L a[],L b[],int n){
- if(n==){b[]=; return;}
- static L lnb[M]; memset(lnb,,n<<);
- getexp(a,b,n>>); getln(b,lnb,n);
- for(int i=;i<n;i++) lnb[i]=(a[i]-lnb[i]+MOD)%MOD,b[i+n]=;
- lnb[n]=;
- lnb[]=(lnb[]+)%MOD;
- NTT(lnb,n<<,); NTT(b,n<<,);
- for(int i=;i<(n<<);i++) b[i]=b[i]*lnb[i]%MOD;
- NTT(b,n<<,-);
- for(int i=;i<n;i++) b[i+n]=;
- }
- L a[M]={},b[M]={};
- L fac[M]={},invfac[M]={};
- int n,k,m;
- L solve(){
- memset(a,,sizeof(a));
- memset(b,,sizeof(b));
- int nn=; while(nn<=n) nn<<=;
- for(int i=;i<=m;i++) a[i]=invfac[i];
- L hh=a[],invhh=pow_mod(hh,MOD-);
- for(int i=;i<nn;i++) a[i]=a[i]*invhh%MOD;
- getln(a,b,nn);
- for(int i=;i<nn;i++) b[i]=b[i]*k%MOD;
- getexp(b,a,nn);
- hh=pow_mod(hh,k);
- for(int i=;i<nn;i++) a[i]=a[i]*hh%MOD;
- return a[n];
- }
- int main(){
- scanf("%d%d%d",&n,&k,&m);
- fac[]=; for(int i=;i<M;i++) fac[i]=fac[i-]*i%MOD;
- invfac[M-]=pow_mod(fac[M-],MOD-);
- for(int i=M-;~i;i--) invfac[i]=invfac[i+]*(i+)%MOD;
- L res1=solve();
- m--;
- L res2=solve();
- cout<<(res1-res2+MOD)*fac[n]%MOD<<endl;
- }
【xsy2479】counting 生成函数+多项式快速幂的更多相关文章
- 【bzoj3684】 大朋友和多叉树 生成函数+多项式快速幂+拉格朗日反演
这题一看就觉得是生成函数的题... 我们不妨去推下此题的生成函数,设生成函数为$F(x)$,则$[x^s]F(x)$即为答案. 根据题意,我们得到 $F(x)=x+\sum_{i∈D} F^i(x)$ ...
- BZOJ3992 [SDOI2015]序列统计 【生成函数 + 多项式快速幂】
题目 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数 列,数列中的每个数都属于集合S.小C用这个生成器生成了许多这样的数列.但是小C有一个问题 ...
- AtCoder AGC019E Shuffle and Swap (DP、FFT、多项式求逆、多项式快速幂)
题目链接 https://atcoder.jp/contests/agc019/tasks/agc019_e 题解 tourist的神仙E题啊做不来做不来--这题我好像想歪了啊= =-- 首先我们可以 ...
- [SDOI2015]序列统计(多项式快速幂)
题目描述 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S.小C用这个生成器生成了许多这样的数列.但是小C有一个问 ...
- BZOJ3645: Maze(FFT多项式快速幂)
Description 众维拉先后在中土大陆上创造了精灵.人类以及矮人,其中矮人是生性喜好常年居住在地下的洞穴的存在,他们挖掘矿物甚至宝石,甚至用他们的勤劳勇敢智慧在地底下创造出了辉煌宏大的宫殿,错综 ...
- luoguP5219 无聊的水题 I 多项式快速幂
有一个幼儿园容斥:最大次数恰好为 $m=$ 最大次数最多为 $m$ - 最大次数最多为 $m-1$. 然后来一个多项式快速幂就好了. code: #include <cmath> #in ...
- 2018.12.31 bzoj3992: [SDOI2015]序列统计(生成函数+ntt+快速幂)
传送门 生成函数简单题. 题意:给出一个集合A={a1,a2,...as}A=\{a_1,a_2,...a_s\}A={a1,a2,...as},所有数都在[0,m−1][0,m-1][0,m− ...
- 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂
[BZOJ3992][SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...
- bzoj 3992: [SDOI2015]序列统计【原根+生成函数+NTT+快速幂】
还是没有理解透原根--题目提示其实挺明显的,M是质数,然后1<=x<=M-1 这种计数就容易想到生成函数,但是生成函数是加法,而这里是乘法,所以要想办法变成加法 首先因为0和任何数乘都是0 ...
随机推荐
- 迭代器模块 itertools
无限迭代器 itertools 包自带了三个可以无限迭代的迭代器.这意味着,当你使用他们时,你要知道你需要的到底是最终会停止的迭代器,还是需要无限地迭代下去. 这些无限迭代器在生成数字或者在长度未知的 ...
- Springboot08-项目单元测试(接口测试)
Springboot08-项目单元测试(接口测试) 前言 1-本文重点在于源码层面,分析Springboot单元测试的使用,对于其中的注解.方法等,不会仔细分析: 2-本文项目实例相关配置:Java- ...
- Working days
form FRM_GET_WORKING_DAYS TABLES pt_days CHANGING pv_duration. DATA:ls_xt001w TYPE t001w, lv_sdate T ...
- elementui上传文件
<el-form-item label="上传附件"> <transition name="fade"> <el-upload r ...
- protobuff 编译注意事项
把protoc.exe增加到环境变量path,这样方便运行protoc 生成C++代码 protoc -I=Proto文件路径 –cpp_out=指定输出.h和.cc的目录 Proto文件 具体参数 ...
- Python开发——数据类型【运算符】
算数运算符 比较运算符 赋值运算符 逻辑运算符 成员运算符
- tomcat源码分析-初始化过程
digester 说明: https://www.cnblogs.com/devilwind/p/8192304.html
- 设计模式 工厂模式 使用shared_ptr
参考http://blog.csdn.net/calmreason/article/details/50903729 所有产品继承同一基本类 由工厂保存基类指针 产生各类产品 代码 // 002.cp ...
- UVA 2451 Brackets sequence
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=9 ...
- Activity 重载方法 onStart和onResume、onPause和onStop的区别
Activity 重载方法 onStart和onResume.onPause和onStop的区别 首先了解Activity的四种状态 Running状态:一个新的Activity启动入栈后,它在屏幕最 ...