还不会这题的多项式求逆的算法。

发现每一项都是一个卷积的形式,那么我们可以使用$NTT$来加速,直接做是$O(n^2logn)$的,我们考虑如何加速转移。

可以采用$cdq$分治的思想,对于区间$[l, r]$中的数,先计算出$[l, mid]$中的数对$[mid + 1, r]$中的数的贡献,然后直接累加到右边去。

容易发现,这样子每一次需要用向量$[l,l + 1, l +  2, \dots, mid]$卷上$g$中$[1, 2, \dots, r - l]$。

时间复杂度$O(nlog^2n)$,感觉这东西跑得并不慢鸭。

Code:

  1. #include <cstdio>
  2. #include <cstring>
  3. using namespace std;
  4. typedef long long ll;
  5.  
  6. const int N = 3e5 + ;
  7. const ll P = 998244353LL;
  8.  
  9. int n, lim, pos[N];
  10. ll f[N], g[N], a[N], b[N];
  11.  
  12. template <typename T>
  13. inline void read(T &X) {
  14. X = ; char ch = ; T op = ;
  15. for (; ch > ''|| ch < ''; ch = getchar())
  16. if (ch == '-') op = -;
  17. for (; ch >= '' && ch <= ''; ch = getchar())
  18. X = (X << ) + (X << ) + ch - ;
  19. X *= op;
  20. }
  21.  
  22. template <typename T>
  23. inline void swap(T &x, T &y) {
  24. T t = x; x = y; y = t;
  25. }
  26.  
  27. inline ll fpow(ll x, ll y) {
  28. ll res = 1LL;
  29. for (; y > ; y >>= ) {
  30. if (y & ) res = res * x % P;
  31. x = x * x % P;
  32. }
  33. return res;
  34. }
  35.  
  36. inline void prework(int len) {
  37. int l = ;
  38. for (lim = ; lim <= len; lim <<= , ++l);
  39. for (int i = ; i < lim; i++)
  40. pos[i] = (pos[i >> ] >> ) | ((i & ) << (l - ));
  41. }
  42.  
  43. inline void ntt(ll *c, int opt) {
  44. for (int i = ; i < lim; i++)
  45. if (i < pos[i]) swap(c[i], c[pos[i]]);
  46. for (int i = ; i < lim; i <<= ) {
  47. ll wn = fpow(, (P - ) / (i << ));
  48. if (opt == -) wn = fpow(wn, P - );
  49. for (int len = i << , j = ; j < lim; j += len) {
  50. ll w = ;
  51. for (int k = ; k < i; k++, w = w * wn % P) {
  52. ll x = c[j + k], y = c[j + k + i] * w % P;
  53. c[j + k] = (x + y) % P, c[j + k + i] =(x - y + P) % P;
  54. }
  55. }
  56. }
  57.  
  58. if (opt == -) {
  59. ll inv = fpow(lim, P - );
  60. for (int i = ; i < lim; i++) c[i] = c[i] * inv % P;
  61. }
  62. }
  63.  
  64. void solve(int l, int r) {
  65. if (l == r) {
  66. a[l] = (a[l] + b[l]) % P;
  67. return;
  68. }
  69.  
  70. int mid = ((l + r) >> );
  71. solve(l, mid);
  72.  
  73. prework(r - l + );
  74. for (int i = ; i < lim; i++) g[i] = f[i] = ;
  75. for (int i = l; i <= mid; i++) f[i - l] = a[i];
  76. for (int i = ; i <= r - l; i++) g[i - ] = b[i];
  77. ntt(f, ), ntt(g, );
  78. for (int i = ; i < lim; i++) f[i] = f[i] * g[i] % P;
  79. ntt(f, -);
  80.  
  81. for (int i = mid + ; i <= r; i++) a[i] = (a[i] + f[i - l - ]) % P;
  82.  
  83. solve(mid + , r);
  84. }
  85.  
  86. int main() {
  87. read(n); n--;
  88. for (int i = ; i <= n; i++) read(b[i]);
  89. a[] = ;
  90. solve(, n);
  91.  
  92. for (int i = ; i <= n; i++)
  93. printf("%lld%c", a[i], i == n ? '\n' : ' ');
  94.  
  95. return ;
  96. }

Luogu 4721 【模板】分治 FFT的更多相关文章

  1. 洛谷.4721.[模板]分治FFT(NTT)

    题目链接 换一下形式:\[f_i=\sum_{j=0}^{i-1}f_jg_{i-j}\] 然后就是分治FFT模板了\[f_{i,i\in[mid+1,r]}=\sum_{j=l}^{mid}f_jg ...

  2. 解题:洛谷4721 [模板]分治FFT

    题面 这是CDQ入门题,不要被题目名骗了,这核心根本不在不在FFT上啊=.= 因为后面的项的计算依赖于前面的项,不能直接FFT.所以用CDQ的思想,算出前面然后考虑给后面的贡献 #include< ...

  3. 洛谷 P4721 [模板]分治FFT —— 分治FFT / 多项式求逆

    题目:https://www.luogu.org/problemnew/show/P4721 分治做法,考虑左边对右边的贡献即可: 注意最大用到的 a 的项也不过是 a[r-l] ,所以 NTT 可以 ...

  4. 【洛谷4721】【模板】分治FFT(CDQ分治_NTT)

    题目: 洛谷 4721 分析: 我觉得这个 "分治 FFT " 不能算一种特殊的 FFT ,只是 CDQ 分治里套了个用 FFT (或 NTT)计算的过程,二者是并列关系而不是偏正 ...

  5. 洛谷 4721 【模板】分治 FFT——分治FFT / 多项式求逆

    题目:https://www.luogu.org/problemnew/show/P4721 分治FFT:https://www.cnblogs.com/bztMinamoto/p/9749557.h ...

  6. [题解] Luogu P4721 【模板】分治 FFT

    分治FFT的板子为什么要求逆呢 传送门 这个想法有点\(cdq\)啊,就是考虑分治,在算一段区间的时候,我们把他分成两个一样的区间,然后先做左区间的,算完过后把左区间和\(g\)卷积一下,这样就可以算 ...

  7. luoguP4721 【模板】分治 FFT

    P4721 [模板]分治 FFT 链接 luogu 题目描述 给定长度为 \(n-1\) 的数组 \(g[1],g[2],..,g[n-1]\),求 \(f[0],f[1],..,f[n-1]\),其 ...

  8. 洛谷 P4721 【模板】分治 FFT 解题报告

    P4721 [模板]分治 FFT 题目背景 也可用多项式求逆解决. 题目描述 给定长度为 \(n−1\) 的数组 \(g[1],g[2],\dots,g[n-1]\),求 \(f[0],f[1],\d ...

  9. 分治FFT模板

    题目链接:https://www.luogu.org/problemnew/show/P4721 总结了一下蒟蒻FFT/NTT容易写错的地方: ​ 1.rev数组求错. ​ 2.cdq注意顺序:先递归 ...

  10. [luogu P5349] 幂 解题报告 (分治FFT)

    interlinkage: https://www.luogu.org/problemnew/show/P5349 description: solution: 设$g(x)=\sum_{n=0}^{ ...

随机推荐

  1. 剑指offer-第四章解决面试题思路(二叉收索树和双向链表)

    题目:输入一个二叉收索树,将二叉搜索树转换成排序的双向链表.要求不能创建节点,只能将链表中的指针进行改变. 将复杂的问题简单化:思路:二叉收索树,本身是一个排序结构,中序遍历二叉收索树就可以得到一组排 ...

  2. matlab与modelsim中的文件操作函数

    matlab中 fscanf和fpintf是一对,用fprintf写的必须用fscanf来读. fread和fwrite是一对,用fwrite写的必须用fread来读. 同样的数据,使用fprintf ...

  3. CentOS虚拟机中安装VMWare Tools

    1.单击VMWare的[虚拟机]菜单,选择[安装VMWare Tools]命令 2.接着CentOS系统会自动挂载VMWare  Tools,并自动打开,如果没有打开可以自己去图形界面打开VMWare ...

  4. [原]zeromq框架测试报告

    一.环境: 服务器:linux 4核 16G 虚拟机 1台 客户端:linux 4核 16G 2000台(模拟) 数据包大小:1036字节 二.参数设置: ulimit -n 65536 服务端处理线 ...

  5. List<Map> 排序

    import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.u ...

  6. thinkphp使用自定义类方法

    1.通过Model调用 <?php /** * 积分模型 api接口 */ class ApiModel{ private $url = 'http://js.yunlutong.com/Cus ...

  7. 微信小程序之if操作

    .wxss控制样式 .price-agent{ font-size: 25rpx; color:#ababab; float: left; position: absolute; bottom: 0; ...

  8. MariaDB存在的问题

    MySQL与MariaDB对嵌套的查询语句当中的order by的处理方法不同.MySQL会忠实执行内层查询的排序子句,但是MariaDB会将这个order by去掉,理论依据就是关系理论 --- 一 ...

  9. resharper activate

    K03CHKJCFT-eyJsaWNlbnNlSWQiOiJLMDNDSEtKQ0ZUIiwibGljZW5zZWVOYW1lIjoibnNzIDEwMDEiLCJhc3NpZ25lZU5hbWUiO ...

  10. C# 泛型类型参数的约束

    在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制.如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误.这些限制称为约束.约束是使用 where 上 ...