有一个幼儿园容斥:最大次数恰好为 $m=$  最大次数最多为 $m$ - 最大次数最多为 $m-1$.

然后来一个多项式快速幂就好了.

code:

  1. #include <cmath>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <cstdio>
  5. #include <string>
  6. #define ll long long
  7. #define ull unsigned long long
  8. using namespace std;
  9. namespace IO
  10. {
  11. char buf[100000],*p1,*p2;
  12. #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
  13. int rd()
  14. {
  15. int x=0; char s=nc();
  16. while(s<'0') s=nc();
  17. while(s>='0') x=(((x<<2)+x)<<1)+s-'0',s=nc();
  18. return x;
  19. }
  20. void print(int x) {if(x>=10) print(x/10);putchar(x%10+'0');}
  21. void setIO(string s)
  22. {
  23. string in=s+".in";
  24. string out=s+".out";
  25. freopen(in.c_str(),"r",stdin);
  26. // freopen(out.c_str(),"w",stdout);
  27. }
  28. };
  29. const int G=3;
  30. const int N=400005;
  31. const int mod=998244353;
  32. int A[N],B[N],w[2][N],mem[N*100],*ptr=mem,tmpa[N],tmpb[N],aa[N],bb[N];
  33. inline int qpow(int x,int y)
  34. {
  35. int tmp=1;
  36. for(;y;y>>=1,x=(ll)x*x%mod) if(y&1) tmp=(ll)tmp*x%mod;
  37. return tmp;
  38. }
  39. inline int INV(int a) { return qpow(a,mod-2); }
  40. inline void ntt_init(int len)
  41. {
  42. int i,j,k,mid,x,y;
  43. w[1][0]=w[0][0]=1,x=qpow(G,(mod-1)/len),y=qpow(x,mod-2);
  44. for (i=1;i<len;++i) w[0][i]=(ll)w[0][i-1]*x%mod,w[1][i]=(ll)w[1][i-1]*y%mod;
  45. }
  46. void NTT(int *a,int len,int flag)
  47. {
  48. int i,j,k,mid,x,y;
  49. for(i=k=0;i<len;++i)
  50. {
  51. if(i>k) swap(a[i],a[k]);
  52. for(j=len>>1;(k^=j)<j;j>>=1);
  53. }
  54. for(mid=1;mid<len;mid<<=1)
  55. for(i=0;i<len;i+=mid<<1)
  56. for(j=0;j<mid;++j)
  57. {
  58. x=a[i+j], y=(ll)w[flag==-1][len/(mid<<1)*j]*a[i+j+mid]%mod;
  59. a[i+j]=(x+y)%mod;
  60. a[i+j+mid]=(x-y+mod)%mod;
  61. }
  62. if(flag==-1)
  63. {
  64. int rev=INV(len);
  65. for(i=0;i<len;++i) a[i]=(ll)a[i]*rev%mod;
  66. }
  67. }
  68. inline void getinv(int *a,int *b,int len,int la)
  69. {
  70. if(len==1) { b[0]=INV(a[0]); return; }
  71. getinv(a,b,len>>1,la);
  72. int l=len<<1,i;
  73. memset(A,0,l*sizeof(A[0]));
  74. memset(B,0,l*sizeof(A[0]));
  75. memcpy(A,a,min(la,len)*sizeof(a[0]));
  76. memcpy(B,b,len*sizeof(b[0]));
  77. ntt_init(l);
  78. NTT(A,l,1),NTT(B,l,1);
  79. for(i=0;i<l;++i) A[i]=((ll)2-(ll)A[i]*B[i]%mod+mod)*B[i]%mod;
  80. NTT(A,l,-1);
  81. memcpy(b,A,len<<2);
  82. }
  83. void get_dao(int *a,int *b,int len)
  84. {
  85. for(int i=1;i<len;++i) b[i-1]=(ll)i*a[i]%mod;
  86. b[len-1]=0;
  87. }
  88. void get_jifen(int *a,int *b,int len)
  89. {
  90. for(int i=1;i<len;++i) b[i]=(ll)INV(i)*a[i-1]%mod;
  91. b[0]=0;
  92. }
  93. void get_ln(int *a,int *b,int len,int la)
  94. {
  95. int l=len<<1,i;
  96. memset(tmpa,0,l<<2);
  97. memset(tmpb,0,l<<2);
  98. get_dao(a,tmpa,min(len,la));
  99. getinv(a,tmpb,len,la);
  100. ntt_init(l);
  101. NTT(tmpa,l,1),NTT(tmpb,l,1);
  102. for(i=0;i<l;++i) tmpa[i]=(ll)tmpa[i]*tmpb[i]%mod;
  103. NTT(tmpa,l,-1);
  104. get_jifen(tmpa,b,len);
  105. }
  106. void get_exp(int *a,int *b,int len,int la)
  107. {
  108. if(len==1) { b[0]=1; return; }
  109. int l=len<<1,i;
  110. get_exp(a,b,len>>1,la);
  111. for(i=0;i<l;++i) aa[i]=bb[i]=0;
  112. for(i=0;i<(len>>1);++i) aa[i]=b[i];
  113. get_ln(b,bb,len,len>>1);
  114. for(i=0;i<len;++i) bb[i]=(ll)(mod-bb[i]+(i>=la?0:a[i]))%mod;
  115. bb[0]=(bb[0]+1)%mod;
  116. ntt_init(l);
  117. NTT(aa,l,1),NTT(bb,l,1);
  118. for(i=0;i<l;++i) aa[i]=(ll)aa[i]*bb[i]%mod;
  119. NTT(aa,l,-1);
  120. for(i=0;i<len;++i) b[i]=aa[i];
  121. }
  122. struct poly
  123. {
  124. int len,*a;
  125. poly(){}
  126. poly(int l) {len=l,a=ptr,ptr+=l; }
  127. inline void rev() { reverse(a,a+len); }
  128. inline void fix(int l) {len=l,a=ptr,ptr+=l;}
  129. inline void get_mod(int l) { for(int i=l;i<len;++i) a[i]=0; len=l; }
  130. inline poly dao()
  131. {
  132. poly re(len-1);
  133. for(int i=1;i<len;++i) re.a[i-1]=(ll)i*a[i]%mod;
  134. return re;
  135. }
  136. inline poly jifen()
  137. {
  138. poly c;
  139. c.fix(len+1);
  140. c.a[0]=0;
  141. for(int i=1;i<=len;++i) c.a[i]=(ll)a[i-1]*INV(i)%mod;
  142. return c;
  143. }
  144. inline poly Inv(int l)
  145. {
  146. int lim=1;
  147. while(lim<=l) lim<<=1;
  148. poly b(lim);
  149. getinv(a,b.a,lim,len);
  150. b.get_mod(l);
  151. return b;
  152. }
  153. inline poly ln(int l)
  154. {
  155. int lim=1;
  156. while(lim<=l) lim<<=1;
  157. poly b(lim);
  158. get_ln(a,b.a,lim,len);
  159. return b;
  160. }
  161. inline poly exp(int l)
  162. {
  163. int lim=1;
  164. while(lim<=l) lim<<=1;
  165. poly b(lim);
  166. get_exp(a,b.a,lim,len);
  167. return b;
  168. }
  169. inline poly q_pow(int k,int l)
  170. {
  171. int lim=1;
  172. while(lim<=l) lim<<=1;
  173. poly b(lim),c(lim);
  174. get_ln(a,b.a,lim,len);
  175. for(int i=0;i<b.len;++i) b.a[i]=(ll)b.a[i]*k%mod;
  176. get_exp(b.a,c.a,lim,b.len);
  177. c.get_mod(l);
  178. return c;
  179. }
  180. inline poly operator*(const poly &b) const
  181. {
  182. poly c(len+b.len-1);
  183. if(c.len<=500)
  184. {
  185. for(int i=0;i<len;++i)
  186. if(a[i]) for(int j=0;j<b.len;++j) c.a[i+j]=(c.a[i+j]+(ll)(a[i])*b.a[j])%mod;
  187. return c;
  188. }
  189. int n=1;
  190. while(n<(len+b.len)) n<<=1;
  191. memset(A,0,n<<2);
  192. memset(B,0,n<<2);
  193. memcpy(A,a,len<<2);
  194. memcpy(B,b.a,b.len<<2);
  195. ntt_init(n);
  196. NTT(A,n,1), NTT(B,n,1);
  197. for(int i=0;i<n;++i) A[i]=(ll)A[i]*B[i]%mod;
  198. NTT(A,n,-1);
  199. memcpy(c.a,A,c.len<<2);
  200. return c;
  201. }
  202. poly operator+(const poly &b) const
  203. {
  204. poly c(max(len,b.len));
  205. for(int i=0;i<c.len;++i) c.a[i]=((i<len?a[i]:0)+(i<b.len?b.a[i]:0))%mod;
  206. return c;
  207. }
  208. poly operator-(const poly &b) const
  209. {
  210. poly c(len);
  211. for(int i=0;i<len;++i)
  212. {
  213. if(i>=b.len) c.a[i]=a[i];
  214. else c.a[i]=(a[i]-b.a[i]+mod)%mod;
  215. }
  216. return c;
  217. }
  218. poly operator/(poly u)
  219. {
  220. int n=len,m=u.len,l=1;
  221. while(l<(n-m+1)) l<<=1;
  222. rev(),u.rev();
  223. poly v=u.Inv(l);
  224. v.get_mod(n-m+1);
  225. poly re=(*this)*v;
  226. rev(),u.rev();
  227. re.get_mod(n-m+1);
  228. re.rev();
  229. return re;
  230. }
  231. poly operator%(poly u)
  232. {
  233. poly re=(*this)-u*(*this/u);
  234. re.get_mod(u.len-1);
  235. return re;
  236. }
  237. };
  238. #define MAX 200005
  239. int fac[N],inv[N],n,m;
  240. void init()
  241. {
  242. fac[0]=inv[0]=1;
  243. int i,j;
  244. for(i=1;i<MAX;++i) fac[i]=(ll)fac[i-1]*i%mod,inv[i]=INV(fac[i]);
  245. }
  246. // 最大出现次数为 k
  247. int calc(int k)
  248. {
  249. poly g(n);
  250. int i,j;
  251. for(i=0;i<=k;++i) g.a[i]=inv[i];
  252. g=g.q_pow(n,n);
  253. return (ll)fac[n-2]*g.a[n-2]%mod;
  254. }
  255. int main()
  256. {
  257. // IO::setIO("input");
  258. init();
  259. int i,j;
  260. scanf("%d%d",&n,&m);
  261. printf("%d\n",(ll)(calc(m-1)-calc(m-2)+mod)%mod);
  262. return 0;
  263. }

  

luoguP5219 无聊的水题 I 多项式快速幂的更多相关文章

  1. 洛谷P5219 无聊的水题 I [prufer序列,生成函数,NTT]

    传送门 思路 有标号无根树的计数,还和度数有关,显然可以想到prufer序列. 问题就等价于求长度为\(n-2\),值域为\([1,n]\),出现次数最多的恰好出现\(m-1\)次,这样的序列有哪些. ...

  2. 【xsy2479】counting 生成函数+多项式快速幂

    题目大意:在字符集大小为$m$的情况下,有多少种构造长度为$n$的字符串$s$的方案,使得$C(s)=k$.其中$C(s)$表示字符串$s$中出现次数最多的字符的出现次数. 对$998244353$取 ...

  3. 【bzoj3684】 大朋友和多叉树 生成函数+多项式快速幂+拉格朗日反演

    这题一看就觉得是生成函数的题... 我们不妨去推下此题的生成函数,设生成函数为$F(x)$,则$[x^s]F(x)$即为答案. 根据题意,我们得到 $F(x)=x+\sum_{i∈D} F^i(x)$ ...

  4. BZOJ3645: Maze(FFT多项式快速幂)

    Description 众维拉先后在中土大陆上创造了精灵.人类以及矮人,其中矮人是生性喜好常年居住在地下的洞穴的存在,他们挖掘矿物甚至宝石,甚至用他们的勤劳勇敢智慧在地底下创造出了辉煌宏大的宫殿,错综 ...

  5. AtCoder AGC019E Shuffle and Swap (DP、FFT、多项式求逆、多项式快速幂)

    题目链接 https://atcoder.jp/contests/agc019/tasks/agc019_e 题解 tourist的神仙E题啊做不来做不来--这题我好像想歪了啊= =-- 首先我们可以 ...

  6. [SDOI2015]序列统计(多项式快速幂)

    题目描述 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S.小C用这个生成器生成了许多这样的数列.但是小C有一个问 ...

  7. 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂

    [BZOJ3992][SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...

  8. (中等) CF 576D Flights for Regular Customers (#319 Div1 D题),矩阵快速幂。

    In the country there are exactly n cities numbered with positive integers from 1 to n. In each city ...

  9. E题:Water Problem(快速幂模板)

    题目大意:原题链接  题解链接 解题思路:令x=x-1代入原等式得到新的等式,两式相加,将sin()部分抵消掉,得到只含有f(x)的状态转移方程f(x+1)=f(x)+f(x-2)+f(x-3),然后 ...

随机推荐

  1. Python学习框架(持续更新)

    1.数据类型 整型:整数,1.2.3...这种 浮点型:简单理解就是小数,1.23.3.141572653等等 字符型:“这是字符”,简单说就是我们说的话,都可以作为字符 布尔值:只有2种,true. ...

  2. HTML兼容问题及解决办法

    标准浏览器子元素不会撑开父元素设置好的宽度,IE6下会的: <style> .box{ width:400px;} .left{ width:200px;height:300px;back ...

  3. ajax 原生js封装ajax [转]

    /* 封装ajax函数 * @param {string}opt.type http连接的方式,包括POST和GET两种方式 * @param {string}opt.url 发送请求的url * @ ...

  4. Python3(五) 包、模块、函数与变量作用域

    一.Python项目的组织结构 最顶级的组织结构:包(文件夹) 第二个层级:模块(文件) 第三个层级:类 第四个层级:函数.变量(不属于组织结构,是类本身的特性) 二.Python包与模块的名字 1. ...

  5. windows、linux 下启用mysql日志功能

    在默认情况下,mysql安装是没有启用日志管理功能的,这为后续的维护带来很多不便的地方. 查看是否启用了日志mysql>show variables like 'log_bin'; 怎样知道当前 ...

  6. 小程序websocket心跳库——websocket-heartbeat-miniprogram

    前言 在16年的时候因为项目接触到websocket,而后对心跳重连做了一次总结,写了篇博客,而后18年对之前github上的demo代码进行了再次开发和开源,最终封装成库.如下: 博客:https: ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统--网页版本代码生成器

    1.单列表模式 2.树形列表模式 3.左右列表模式 4.左右树形和列表结合模式 一 简介 网页版代码生成器需要运行项目,非常有趣,可以用来研究,和自定义一些自己的代码习惯 按界面生成:可生成单个页面和 ...

  8. Docker Compose 模板文件 V2

    模板文件是使用Compose的核心,默认模板文件名称为docker-compose.yml ,格式为YAML格式. 目录结构 [root@localhost ~]# tree /opt/compose ...

  9. centos7.5优化系统脚本(虚拟机下)

    #!/usr/bin/bash #安装常用软件,首先必须自行调整好网卡配置文件,保证可以上网,否则,下列优化会失败 yum -y install wget vim lrzsz bash-complet ...

  10. HDU 5391 水题。

    E - 5 Time Limit:1500MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Statu ...