传送门

多项式求逆的解法看这里

我们考虑用分治

假设现在已经求出了$[l,mid]$的答案,要计算他们对$[mid+1,r]$的答案的影响

那么对右边部分的点$f_x$的影响就是$f_x+=\sum_{i=l}^{mid}f[i]g[x-i]$

发现右边那个东西可以用卷积快速计算

那么只要一边分治一边跑FFT统计贡献就行了

说是分治FFT实际上代码里写的是NTT……

而且分治FFT跑得好慢多项式求逆的速度是它的10倍啊……

  1. //minamoto
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<algorithm>
  5. using namespace std;
  6. #define swap(x,y) (x^=y,y^=x,x^=y)
  7. #define mul(x,y) (1ll*x*y%P)
  8. #define add(x,y) (x+y>=P?x+y-P:x+y)
  9. #define dec(x,y) (x-y<0?x-y+P:x-y)
  10. using namespace std;
  11. #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
  12. char buf[<<],*p1=buf,*p2=buf;
  13. inline int read(){
  14. #define num ch-'0'
  15. char ch;bool flag=;int res;
  16. while(!isdigit(ch=getc()))
  17. (ch=='-')&&(flag=true);
  18. for(res=num;isdigit(ch=getc());res=res*+num);
  19. (flag)&&(res=-res);
  20. #undef num
  21. return res;
  22. }
  23. char sr[<<],z[];int C=-,Z;
  24. inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
  25. inline void print(int x){
  26. if(C><<)Ot();if(x<)sr[++C]=,x=-x;
  27. while(z[++Z]=x%+,x/=);
  28. while(sr[++C]=z[Z],--Z);sr[++C]=' ';
  29. }
  30. const int N=,P=;
  31. inline int ksm(int a,int b){
  32. int res=;
  33. while(b){
  34. if(b&) res=mul(res,a);
  35. a=mul(a,a),b>>=;
  36. }
  37. return res;
  38. }
  39. int n,r[N],g[N],f[N],A[N],B[N],O[N],limit,l;
  40. inline void init(int len){
  41. limit=,l=;
  42. while(limit<len*) limit<<=,++l;
  43. for(int i=;i<limit;++i)
  44. r[i]=(r[i>>]>>)|((i&)<<(l-));
  45. }
  46. void NTT(int *A,int type){
  47. for(int i=;i<limit;++i)
  48. if(i<r[i]) swap(A[i],A[r[i]]);
  49. for(int mid=;mid<limit;mid<<=){
  50. int R=mid<<,Wn=ksm(,(P-)/R);O[]=;
  51. for(int j=;j<mid;++j) O[j]=mul(O[j-],Wn);
  52. for(int j=;j<limit;j+=R){
  53. for(int k=;k<mid;++k){
  54. int x=A[j+k],y=mul(O[k],A[j+k+mid]);
  55. A[j+k]=add(x,y),A[j+k+mid]=dec(x,y);
  56. }
  57. }
  58. }
  59. if(type==-){
  60. reverse(A+,A+limit);
  61. for(int i=,inv=ksm(limit,P-);i<limit;++i)
  62. A[i]=mul(A[i],inv);
  63. }
  64. }
  65. void CDQ(int *a,int *b,int l,int r){
  66. if(l==r) return;
  67. int mid=(l+r)>>;CDQ(a,b,l,mid);
  68. init(r-l+);
  69. for(int i=;i<limit;++i) A[i]=B[i]=;
  70. for(int i=l;i<=mid;++i) A[i-l]=a[i];
  71. for(int i=;i<=r-l;++i) B[i]=b[i];
  72. NTT(A,),NTT(B,);
  73. for(int i=;i<limit;++i) A[i]=mul(A[i],B[i]);
  74. NTT(A,-);
  75. for(int i=mid+;i<=r;++i) a[i]=add(a[i],A[i-l]);
  76. CDQ(a,b,mid+,r);
  77. }
  78. int main(){
  79. // freopen("testdata.in","r",stdin);
  80. n=read();
  81. for(int i=;i<n;++i) g[i]=read();f[]=;
  82. CDQ(f,g,,n-);
  83. for(int i=;i<n;++i) print(f[i]);
  84. Ot();
  85. return ;
  86. }

洛谷P4721 【模板】分治 FFT(分治FFT)的更多相关文章

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

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

  2. [洛谷P3806] [模板] 点分治1

    洛谷 P3806 传送门 这个点分治都不用减掉子树里的了,直接搞就行了. 注意第63行 if(qu[k]>=buf[j]) 不能不写,也不能写成>. 因为这个WA了半天...... 如果m ...

  3. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  4. 洛谷.1919.[模板]A*B Problem升级版(FFT)

    题目链接:洛谷.BZOJ2179 //将乘数拆成 a0*10^n + a1*10^(n-1) + ... + a_n-1的形式 //可以发现多项式乘法就模拟了竖式乘法 所以用FFT即可 注意处理进位 ...

  5. 洛谷.3803.[模板]多项式乘法(FFT)

    题目链接:洛谷.LOJ. FFT相关:快速傅里叶变换(FFT)详解.FFT总结.从多项式乘法到快速傅里叶变换. 5.4 又看了一遍,这个也不错. 2019.3.7 叕看了一遍,推荐这个. #inclu ...

  6. 洛谷 P4245 [模板]任意模数NTT —— 三模数NTT / 拆系数FFT(MTT)

    题目:https://www.luogu.org/problemnew/show/P4245 用三模数NTT做,需要注意时间和细节: 注意各种地方要取模!传入 upt() 里面的数一定要不超过2倍 m ...

  7. 洛谷P3810 陌上花开(CDQ分治)

    洛谷P3810 陌上花开 传送门 题解: CDQ分治模板题. 一维排序,二维归并,三维树状数组. 核心思想是分治,即计算左边区间对右边区间的影响. 代码如下: #include <bits/st ...

  8. 洛谷SP22343 NORMA2 - Norma(分治,前缀和)

    洛谷题目传送门 这题推式子恶心..... 考虑分治,每次统计跨过\(mid\)的所有区间的答案和.\(i\)从\(mid-1\)到\(l\)枚举,统计以\(i\)为左端点的所有区间. 我们先维护好\( ...

  9. Poj1741/洛谷P4718 Tree(点分治)

    题面 有多组数据:Poj 无多组数据:洛谷 题解 点分治板子题,\(calc\)的时候搞一个\(two\ pointers\)扫一下统计答案就行了. #include <cmath> #i ...

随机推荐

  1. requestAnimationFrame 的实验性实践

    记得当 requestAnimationFrame 出现时我立马就石更了,就跟初次玩耍 transition 时一样,欣喜若狂... 然后,然后特么的就懵逼了,这明明就是口挖不通的深井呀(如果是我傻, ...

  2. 个人对于css sprite的一点点见解

    css sprite即CSS雪碧图又称CSS精灵.它存在的一个主要作用就是:减少了网页的http请求次数,从而大大的提高了页面的性能,节省时间和带宽. 例如 这样算下来.CSS sprite真的是个很 ...

  3. 前端之CSS进阶

    一.CSS属性操作 1.背景属性 常用: background-color 规定要使用的背景颜色 background-image 规定要使用的背景图像 background-repeat 规定如何重 ...

  4. 摊铺机基本参数介绍(三一重工SSP220C-5)

    三一重工SSP220C-5稳定土摊铺机参数 SSP系列稳定土摊铺机SSP220C-5 动力强劲162kw 动力充分满足摊铺机各种工况下动力需求 高效任何工况,确保摊铺能力大于900t/h,行业内绝无仅 ...

  5. 主攻ASP.NET MVC4.0之重生:ASP.NET MVC Web API

    UserController代码: using GignSoft.Models; using System; using System.Collections.Generic; using Syste ...

  6. Python的operator.itemgetter函数和sorted函数

    写这篇文章的目的是之前在<机器学习实战>用Python3实现KNN算法时用到的几个函数不太懂, 地址: 1- https://github.com/hitergelei/Self-Lear ...

  7. Go HelloWorld 网络版和并发版

    网络版 package main import ( "net/http" "fmt" ) func main() { http.HandleFunc(" ...

  8. Fatal error: cannot create 'R_TempDir'

    [user@mgmt dir]$ R Fatal error: cannot create 'R_TempDir' [user@mgmt dir]$ ll -ad /tmp drwxrwxrwt. 2 ...

  9. Oracle数据库连接生成DDL

    package com.bbkj; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepare ...

  10. python练习_三级菜单

    python练习_三级菜单 需求: 做一个地区查询三级菜单,输入一级能够打印下一级 在第三级个第二级输入e可以返回上一级 在任意一级输入q则退出程序 以下代码实现的功能与思路: 功能: (1)通过In ...