传送门

我是用多项式求逆做的因为分治FFT看不懂……

upd:分治FFT的看这里

话说这个万恶的生成函数到底是什么东西……

我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x)=\sum_{i=0}^\infty g_ix^i$,且$g_0=0$

这俩玩意儿似乎就是$f(x)$和$g(x)$的生成函数

那么就有$$F(x)G(x)=\sum_{i=0}^\infty x^i\sum_{j+k=i}f_jg_k$$

然后根据题目,有$$f_i=\sum_{j=1}^if_{i-j}g_j$$

然后因为$g_0=0$,所以

$$f_i=\sum_{j+k=i}f_jg_k$$

又因为该式子只有在$i=0$时不成立,于是代入并手算一下$i=0$的时候,可得$$F(x)G(x)=\sum_{i=0}^\infty f_ix^i-f_0x^0$$

又因为$f_0=x^0=1$,可得$$F(x)G(x)=F(x)-1$$

然后我们只要求它的前$n$项就可以了,所以取模$$F(x)G(x)\equiv F(x)-1\pmod{x^n}$$

然后移项$$F(x)\equiv\frac{1}{1-G(x)}\pmod{x^n}$$

$$F(x)\equiv(1-G(x))^{-1}\pmod{x^n}$$

然后去隔壁把多项式求逆的板子抄来就好了

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

洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)的更多相关文章

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

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

  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. 洛谷P4233 射命丸文的笔记 【多项式求逆】

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

  4. 洛谷 P5162 WD与积木【多项式求逆】

    设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 ...

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

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

  6. luogu P4726 多项式指数函数(模板题FFT、多项式求逆、多项式对数函数)

    手动博客搬家: 本文发表于20181127 08:39:42, 原地址https://blog.csdn.net/suncongbo/article/details/84559818 题目链接: ht ...

  7. 洛谷P4841 城市规划(生成函数 多项式求逆)

    题意 链接 Sol Orz yyb 一开始想的是直接设\(f_i\)表示\(i\)个点的无向联通图个数,枚举最后一个联通块转移,发现有一种情况转移不到... 正解是先设\(g(n)\)表示\(n\)个 ...

  8. luogu P4725 多项式对数函数 (模板题、FFT、多项式求逆、求导和积分)

    手动博客搬家: 本文发表于20181125 13:25:03, 原地址https://blog.csdn.net/suncongbo/article/details/84487306 题目链接: ht ...

  9. 【XSY2612】Comb Avoiding Trees 生成函数 多项式求逆 矩阵快速幂

    题目大意 本题的满二叉树定义为:不存在只有一个儿子的节点的二叉树. 定义一棵满二叉树\(A\)包含满二叉树\(B\)当且经当\(A\)可以通过下列三种操作变成\(B\): 把一个节点的两个儿子同时删掉 ...

随机推荐

  1. bash批量去前缀

    #!/bin/sh for aFile in *; do oldfile=`basename "$aFile"` newfile=${oldfile::} echo ${oldfi ...

  2. POJ 1068 Parencodings【水模拟--数括号】

    链接: http://poj.org/problem?id=1068 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27454#probl ...

  3. 销售订单、外向交货单、交货 bapi

    转自[http://www.cnblogs.com/elegantok/archive/2009/10/18/1585398.html]***********SALES ORDER INPUT CRE ...

  4. python基础21 ------python基础之socket编程

    一.C/S架构和B/S架构的简介 略 二.osi七层模型 略 三.socket层 1.如图所示: socket层是存在于应用层和传输层直接抽象出来的一层. 2.socket层是什么? Socket是应 ...

  5. SpringBoot学习笔记(3):静态资源处理

    SpringBoot学习笔记(3):静态资源处理 在web开发中,静态资源的访问是必不可少的,如:Html.图片.js.css 等资源的访问. Spring Boot 对静态资源访问提供了很好的支持, ...

  6. Elasticsearch使用记录

    Elasticsearch使用记录 Elasticsearch的搭建方法 1.RPM方式搭建 首先去官网[https://www.elastic.co/downloads/elasticsearch# ...

  7. [原创]java WEB学习笔记22:MVC案例完整实践(part 3)---多个请求对应一个Servlet解析

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  8. jQuery悬浮焦点图宽屏

    在线演示 本地下载

  9. 让win10登陆时不再要求手动输入用户名

    如果windows每次登陆都要求手动输入用户名,可以用如下的方法避免: Windows10专业版.企业版和教育版用户 在运行或Cortana搜索栏输入secpol.msc后,按回车键进入"本 ...

  10. HDU2612 -暑假集训-搜索进阶N

     http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82828#problem/N这两天总是因为一些小错误耽误时间,我希望自己可以细心点.珍惜 ...