设f[i]为i个积木能堆出来的种类,g[i]为i个积木能堆出来的种类和

\[f[n]=\sum_{i=1}^{n}C_{n}^{i}g[n-i]
\]

\[g[n]=\sum_{i=1}^{n}C_{n}^{i}f[n-i]+g[n]
\]

理解就是选出包含最后一个的块,然后剩下的按照之前的拼

化简,设s为\( \frac{1}{n!} \),G为\( \frac{g[n]}{n!} \),F为\( \frac{fn]}{n!} \),把组合数拆开,变成卷积形式,然后化简就变成

\[F=\frac{1}{1-S}
\]

\[G=F*(F-1)
\]

用多项式求逆即可

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. const int N=1000005,mod=998244353;
  5. int T,n=1e5+5,s[N],f[N],g[N],a[N],b[N],c[N],t[N],fac[N],inv[N],re[N],lm,bt,ans[N];
  6. int read()
  7. {
  8. int r=0,f=1;
  9. char p=getchar();
  10. while(p>'9'||p<'0')
  11. {
  12. if(p=='-')
  13. f=-1;
  14. p=getchar();
  15. }
  16. while(p>='0'&&p<='9')
  17. {
  18. r=r*10+p-48;
  19. p=getchar();
  20. }
  21. return r*f;
  22. }
  23. int ksm(int a,int b)
  24. {
  25. int r=1;
  26. while(b)
  27. {
  28. if(b&1)
  29. r=1ll*r*a%mod;
  30. a=1ll*a*a%mod;
  31. b>>=1;
  32. }
  33. return r;
  34. }
  35. void dft(int a[],int f)
  36. {
  37. for(int i=0;i<lm;i++)
  38. if(i<re[i])
  39. swap(a[i],a[re[i]]);
  40. for(int i=1;i<lm;i<<=1)
  41. {
  42. int wi=ksm(3,(mod-1)/(i*2));
  43. if(f==-1)
  44. wi=ksm(wi,mod-2);
  45. for(int k=0;k<lm;k+=(i<<1))
  46. {
  47. int w=1,x,y;
  48. for(int j=0;j<i;j++)
  49. {
  50. x=a[j+k];
  51. y=1ll*a[i+j+k]*w%mod;
  52. a[j+k]=(x+y)%mod;
  53. a[i+j+k]=(x-y+mod)%mod;
  54. w=1ll*w*wi%mod;
  55. }
  56. }
  57. }
  58. if(f==-1)
  59. {
  60. int ni=ksm(lm,mod-2);
  61. for(int i=0;i<lm;i++)
  62. a[i]=1ll*a[i]*ni%mod;
  63. }
  64. }
  65. void clc(int len)
  66. {//cerr<<len<<endl;
  67. if(len==0)
  68. {
  69. c[0]=ksm(s[0],mod-2);
  70. return;
  71. }
  72. clc(len>>1);
  73. for(bt=1;(1<<bt)<=len;bt++);
  74. lm=(1<<bt);
  75. for(int i=0;i<lm;i++)
  76. re[i]=(re[i>>1]>>1)|((i&1)<<(bt-1));
  77. for(int i=0;i<len;i++)
  78. t[i]=s[i];
  79. dft(t,1);
  80. dft(c,1);
  81. for(int i=0;i<lm;i++)
  82. c[i]=1ll*c[i]*(mod+2-1ll*c[i]*t[i]%mod)%mod;
  83. dft(c,-1);
  84. for(int i=len;i<=2*lm+1;i++)
  85. c[i]=0;
  86. for(int i=0;i<=2*lm+1;i++)
  87. t[i]=0;
  88. }
  89. int main()
  90. {
  91. n=1e5+5;
  92. fac[0]=inv[0]=1;
  93. for(int i=1;i<=n;i++)
  94. fac[i]=1ll*fac[i-1]*i%mod;
  95. inv[n]=ksm(fac[n],mod-2);
  96. for(int i=n-1;i>=1;i--)
  97. inv[i]=1ll*inv[i+1]*(i+1)%mod;
  98. for(int i=1;i<=n;i++)
  99. s[i]=mod-inv[i];
  100. s[0]++;
  101. for(bt=1;(1<<bt)<=2*n;bt++);
  102. lm=(1<<bt);
  103. clc(lm);
  104. for(int i=1;i<=n;i++)
  105. a[i]=b[i]=f[i]=c[i];
  106. f[0]=a[0]=1,b[0]=0;
  107. // for(int i=0;i<=10;i++)
  108. // cerr<<f[i]<<" ";cerr<<endl;
  109. for(bt=1;(1<<bt)<=2*n;bt++);
  110. lm=(1<<bt);
  111. for(int i=0;i<lm;i++)
  112. re[i]=(re[i>>1]>>1)|((i&1)<<(bt-1));
  113. dft(a,1);
  114. dft(b,1);
  115. for(int i=0;i<lm;i++)
  116. g[i]=1ll*a[i]*b[i]%mod;
  117. dft(g,-1);
  118. for(int i=1;i<=n;i++)
  119. ans[i]=1ll*g[i]*ksm(f[i],mod-2)%mod;//,printf("%d\n",ans[i]);
  120. T=read();
  121. while(T--)
  122. printf("%d\n",ans[read()]);
  123. return 0;
  124. }

洛谷 P5162 WD与积木【多项式求逆】的更多相关文章

  1. 洛谷 P5162 WD与积木 解题报告

    P5162 WD与积木 题目背景 WD整日沉浸在积木中,无法自拔-- 题目描述 WD想买\(n\)块积木,商场中每块积木的高度都是\(1\),俯视图为正方形(边长不一定相同).由于一些特殊原因,商家会 ...

  2. 洛谷P5162 WD与积木 [DP,NTT]

    传送门 思路 真是非常套路的一道题-- 考虑\(DP\):设\(f_n\)为\(n\)个积木能搭出的方案数,\(g_n\)为所有方案的高度之和. 容易得到转移方程: \[ \begin{align*} ...

  3. 洛谷P4238【模板】多项式求逆

    洛谷P4238 多项式求逆:http://blog.miskcoo.com/2015/05/polynomial-inverse 注意:直接在点值表达下做$B(x) \equiv 2B'(x) - A ...

  4. [Luogu5162]WD与积木(多项式求逆)

    不要以为用上Stirling数就一定离正解更近,FFT都是从DP式本身出发的. 设f[i]为i个积木的所有方案的层数总和,g[i]为i个积木的方案数,则答案为$\frac{f[i]}{g[i]}$ 转 ...

  5. 2018.12.30 洛谷P4238 【模板】多项式求逆

    传送门 多项式求逆模板题. 简单讲讲? 多项式求逆 定义: 对于一个多项式A(x)A(x)A(x),如果存在一个多项式B(x)B(x)B(x),满足B(x)B(x)B(x)的次数小于等于A(x)A(x ...

  6. [洛谷P4238]【模板】多项式求逆

    题目大意:多项式求逆 题解:$ A^{-1}(x) = (2 - B(x) * A(x)) \times B(x) \pmod{x^n} $ ($B(x)$ 为$A(x)$在$x^{\lceil \d ...

  7. 洛谷P4239 【模板】多项式求逆(加强版)(多项式求逆)

    传送门 咱用的是拆系数\(FFT\)因为咱真的不会三模数\(NTT\)-- 简单来说就是把每一次多项式乘法都改成拆系数\(FFT\)就行了 如果您还不会多项式求逆的左转->这里 顺带一提,因为求 ...

  8. 洛谷P4238 【模板】多项式求逆(NTT)

    传送门 学习了一下大佬的->这里 已知多项式$A(x)$,若存在$A(x)B(x)\equiv 1\pmod{x^n}$ 则称$B(x)$为$A(x)$在模$x^n$下的逆元,记做$A^{-1} ...

  9. 洛谷P4233 射命丸文的笔记 【多项式求逆】

    题目链接 洛谷P4233 题解 我们只需求出总的哈密顿回路个数和总的强联通竞赛图个数 对于每条哈密顿回路,我们统计其贡献 一条哈密顿回路就是一个圆排列,有\(\frac{n!}{n}\)种,剩余边随便 ...

随机推荐

  1. 使用nginx+nginx-rtmp-module+ffmpeg搭建流媒体服务器

    参考: 1,使用nginx+nginx-rtmp-module+ffmpeg搭建流媒体服务器笔记(一)http://blog.csdn.net/xdwyyan/article/details/4319 ...

  2. 利用wxpython显示OpenCV图像

    核心代码 import wx, cv2 import numpy as np # Start with a numpy array style image I'll call "source ...

  3. [Android] Gradle 安装

    Gradle安装非常简单,只要从官网下载压缩包,解压,修改一下环境变量即可. 笔者写本篇随笔时,版本是1.12. Windows下安装 1 到官网(http://www.gradle.org/down ...

  4. OC中RAC编程block的基本使用

    在OC中block的基本使用 // // ViewController.h // RAC--test // // Created by Aaron on 17/1/17. // Copyright © ...

  5. 学习html第一天

    网站本身就是软件,软件:一种具有特定功能的程序指令的集合 C/S:C客户端-->S服务器  由程序员开发  客户去下载升级安装,比如魔兽世界 B/S:B浏览器-->S服务器  由程序员开发 ...

  6. matlab之sortrows()函数

    sortrows()函数的格式: sortrows(A,column) A是一个矩阵,如果没有第二个参数column,则默认按照第一列升序排列,如果遇到重复数字,则按照第二列升序排列,依次类推... ...

  7. BZOJ 2020 [Usaco2010 Jan]Buying Feed,II:贪心【定义价值】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2020 题意: FJ开车去买K份食物. 如果他的车上有X份食物,每走一里就花费X元. FJ的 ...

  8. 通过在classpath自动扫描方式把组件纳入spring容器中管理。

    前面的例子我们都是使用xml的bean定义来配置组件,如果组件过多很臃肿.spring2.5引入了组件自动扫描机制,在指定目录下查找标注了@Component.@Service.@Controller ...

  9. codeforces 705B B. Spider Man(组合游戏)

    题目链接: B. Spider Man time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  10. hdu-5778 abs(暴力枚举)

    题目链接: abs Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 131072/131072 K (Java/Others) Pro ...