题目:https://www.luogu.org/problemnew/show/P4721

分治FFT:https://www.cnblogs.com/bztMinamoto/p/9749557.html

     https://blog.csdn.net/VictoryCzt/article/details/82939586

不知为何自己的总是很慢。

觉得是 n 和 m 表示次数的话,len<=n+m;n 和 m 表示项数的话,len<n+m;应该是这样?

这里是 mid-L+1 项和 R-L+1 项的两个多项式相乘,所以 len < (mid-L+1)+(R-L+1);

但这样很慢;发现那个 g[0] = 0 每次浪费了一个位置;所以把 g 的标号都减小1,位置 i 对应的位置标号自然也减小了1;微妙地快了一点。

发现用到的最高次项也只是 R-L-1 次;所以 len<= R-L-1 即可!快了一倍。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define ll long long
  6. using namespace std;
  7. const int N=1e5+,M=N<<,mod=;
  8. int len,r[M],f[M],g[M],a[M],b[M];
  9. int rdn()
  10. {
  11. int ret=;bool fx=;char ch=getchar();
  12. while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
  13. while(ch>=''&&ch<='') ret=ret*+ch-'',ch=getchar();
  14. return fx?ret:-ret;
  15. }
  16. void upd(int &x){x>=mod?x-=mod:;}
  17. int pw(int x,int k)
  18. {int ret=;while(k){if(k&)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=;}return ret;}
  19. void ntt(int *a,bool fx)
  20. {
  21. for(int i=;i<len;i++)
  22. if(i<r[i])swap(a[i],a[r[i]]);
  23. for(int R=;R<=len;R<<=)
  24. {
  25. int Wn=pw( ,(mod-)/R );
  26. if(fx)Wn=pw( Wn,mod- );
  27. for(int i=,m=R>>;i<len;i+=R)
  28. for(int j=,w=;j<m;j++,w=(ll)w*Wn%mod)
  29. {
  30. int x=a[i+j], y=(ll)w*a[i+m+j]%mod;
  31. a[i+j]=x+y; upd(a[i+j]);
  32. a[i+m+j]=x+mod-y; upd(a[i+m+j]);
  33. }
  34. }
  35. if(!fx)return; int inv=pw( len,mod- );
  36. for(int i=;i<len;i++)a[i]=(ll)a[i]*inv%mod;
  37. }
  38. void solve(int L,int R)
  39. {
  40. if(L==R)return;
  41. int mid=L+R>>;
  42. solve(L,mid);
  43. int d=R-L-,i,j;
  44. for(i=,j=L;j<=mid;i++,j++)a[i]=f[j];// d+=i-1;
  45. for(i=,j=R-L;i<j;i++)b[i]=g[i+];// d+=i-1;//+1
  46. for(len=;len<=d;len<<=);
  47. for(i=;i<len;i++)r[i]=(r[i>>]>>)+((i&)?len>>:);
  48. for(i=mid-L+;i<len;i++)a[i]=; for(i=R-L+;i<len;i++)b[i]=;
  49. ntt(a,); ntt(b,);
  50. for(i=;i<len;i++)a[i]=(ll)a[i]*b[i]%mod;
  51. ntt(a,);
  52. for(i=mid+,j=i-L-;i<=R;i++,j++)f[i]+=a[j],upd(f[i]);////j=i-L -1
  53. solve(mid+,R);
  54. }
  55. int main()
  56. {
  57. int n;n=rdn();for(int i=;i<n;i++)g[i]=rdn();
  58. f[]=;
  59. solve(,n-);
  60. for(int i=;i<n;i++)printf("%d ",f[i]);puts("");
  61. return ;
  62. }

多项式做法可参见洛谷自带的题解。

F(x) - f[0] = F(x)*G(x)

F(x) = 1/ ( f[0]-G(x) )

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define ll long long
  6. using namespace std;
  7. const int N=1e5+,M=N<<,mod=;
  8. int a[M],b[M],A[M],len,r[M];
  9. int rdn()
  10. {
  11. int ret=;bool fx=;char ch=getchar();
  12. while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
  13. while(ch>=''&&ch<='') ret=ret*+ch-'',ch=getchar();
  14. return fx?ret:-ret;
  15. }
  16. void upd(int &x){x>=mod?x-=mod:;}
  17. int pw(int x,int k)
  18. {int ret=;while(k){if(k&)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=;}return ret;}
  19. void ntt(int *a,bool fx)
  20. {
  21. for(int i=;i<len;i++)
  22. if(i<r[i])swap(a[i],a[r[i]]);
  23. for(int R=;R<=len;R<<=)
  24. {
  25. int Wn=pw( ,fx?(mod-)-(mod-)/R:(mod-)/R );
  26. for(int i=,m=R>>;i<len;i+=R)
  27. for(int j=,w=;j<m;j++,w=(ll)w*Wn%mod)
  28. {
  29. int x=a[i+j], y=(ll)w*a[i+m+j]%mod;
  30. a[i+j]=x+y; upd(a[i+j]);
  31. a[i+m+j]=x+mod-y; upd(a[i+m+j]);
  32. }
  33. }
  34. if(!fx)return; int inv=pw(len,mod-);
  35. for(int i=;i<len;i++)a[i]=(ll)a[i]*inv%mod;
  36. }
  37. void inv(int n)
  38. {
  39. if(n==){b[]=pw(a[],mod-);return;}
  40. inv(n+>>);
  41. for(len=;len<n<<;len<<=);
  42. for(int i=;i<len;i++)r[i]=(r[i>>]>>)+((i&)?len>>:);
  43. for(int i=;i<n;i++)A[i]=a[i]; for(int i=n;i<len;i++)A[i]=;
  44. ntt(A,); ntt(b,);
  45. for(int i=;i<len;i++)b[i]=((b[i]<<)-(ll)A[i]*b[i]%mod*b[i])%mod+mod,upd(b[i]);
  46. ntt(b,);
  47. for(int i=n;i<len;i++)b[i]=;
  48. }
  49. int main()
  50. {
  51. int n; n=rdn(); for(int i=;i<n;i++)a[i]=mod-rdn(); a[]=;
  52. inv(n);
  53. for(int i=;i<n;i++)printf("%d ",b[i]);puts("");
  54. return ;
  55. }

洛谷 4721 【模板】分治 FFT——分治FFT / 多项式求逆的更多相关文章

  1. 洛谷P3711 仓鼠的数学题(伯努利数+多项式求逆)

    题面 传送门 题解 如果您不知道伯努利数是什么可以去看看这篇文章 首先我们把自然数幂和化成伯努利数的形式 \[\sum_{i=1}^{n-1}i^k={1\over k+1}\sum_{i=0}^k{ ...

  2. 洛谷.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 ...

  3. 洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)

    传送门 我是用多项式求逆做的因为分治FFT看不懂…… upd:分治FFT的看这里 话说这个万恶的生成函数到底是什么东西…… 我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x) ...

  4. BZOJ 4555: [Tjoi2016&Heoi2016]求和 [分治FFT 组合计数 | 多项式求逆]

    4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...

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

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

  6. NOIP 2013 洛谷P1966 火柴排队 (树状数组求逆序对)

    对于a[],b[]两个数组,我们应选取其中一个为基准,再运用树状数组求逆序对的方法就行了. 大佬博客:https://www.cnblogs.com/luckyblock/p/11482130.htm ...

  7. 多项式求逆元详解+模板 【洛谷P4238】多项式求逆

    概述 多项式求逆元是一个非常重要的知识点,许多多项式操作都需要用到该算法,包括多项式取模,除法,开跟,求ln,求exp,快速幂.用快速傅里叶变换和倍增法可以在$O(n log n)$的时间复杂度下求出 ...

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

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

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

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

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

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

随机推荐

  1. codeforces 357

    C 题意: ###n个勇士编号1-n,m个回合对战,每个回合由仍留在游戏里的编号Li~Ri的人参加,胜者为Xi,输的人退出游戏. ###求一个a1-an的序列,若ai为胜者,则ai=0,否则ai=打败 ...

  2. ErrorHandling in asp.net web api

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/error-handling/exception-handling https://d ...

  3. codevs.cn 2776寻找代表元 最大流解法

    网址:http://codevs.cn/problem/2776/ 题目大意: n个社团,m个人,每个社团可以有一个人担任代表,每个人可以担任多个代表,问最多有多少人是代表. 思路:可以建一个图,然后 ...

  4. mysql——主键自动增长&唯一索引

    首先说一下主键和唯一索引的区别 主键:一个数据库的一张表有且仅有一个主键,而且主键不能重复 唯一索引:一个数据库的一张表上唯一索引可以有多个,只是所在唯一索引上的值不能重复,这一点和主键一样 下面我们 ...

  5. Java Collections Framework Java集合框架概览

    Java SE documents -- The Collections Framework http://docs.oracle.com/javase/8/docs/technotes/guides ...

  6. org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 语法分析器在此文档中遇到多个 "64,000" 实体扩展; 这是应用程序施加的限制

    使用SAX解析XML文件.XML文件有1.5G,程序抛出了这个问题: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 语法 ...

  7. WPF的外观装饰类——Border

    public class Border : System.Windows.Controls.Decorator 说明:在另一个元素的周围绘制边框.背景或同时绘制二者.

  8. python面向对象编程学习

    python面向对象编程 基本概念理解 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作 ...

  9. 十 web爬虫讲解2—Scrapy框架爬虫—Scrapy安装—Scrapy指令

    Scrapy框架安装 1.首先,终端执行命令升级pip: python -m pip install --upgrade pip2.安装,wheel(建议网络安装) pip install wheel ...

  10. uva-11020-平衡树

    题目链接https://vjudge.net/problem/UVA-11020 白书例题,依次给出n个点的坐标,定义一个点为优势点当且仅当这个点的左下方区域不包含任何点(但可以与之完全重合):求每加 ...