luogu P4512 多项式除法 (模板题、FFT、多项式求逆)

手动博客搬家: 本文发表于20181206 14:42:53, 原地址https://blog.csdn.net/suncongbo/article/details/84853342

题目链接: https://www.luogu.org/problemnew/show/P4512

没想到这算法这么蠢。。一点都不难啊。。我连这都推不出来我是不是没救了

这个多项式满足\(A(x)=B(x)Q(x)+R(x)\), 如果已知\(R(x)\)是\(0\), 那显然很好处理,求个逆就行了。
那如果有余数呢?很简单,如果我们把这个多项式的系数翻转(reverse),那么\(R(x)\)就从低次项变成了高次项,低次项就不再受\(R(x)\)的而影响了。
这是我们的基本思路。下面我们来形式化这个过程:
\(A(x)=B(x)Q(x)+R(x)\)
对于\(n\)次多项式\(F(x)\)令\(F_R(x)=x^nF(\frac{1}{x})\) (这就是前面所说的reverse操作)
则有\(x^nA(\frac{1}{x})=x^mB(\frac{1}{x})x^{n-m}Q(\frac{1}{x})+x^{m-1}R(\frac{1}{x})x^{n-m+1}\)
\(A_R(x)=B_R(x)Q_R(x)+x^{n-m+1}R_R(x)\)
\(A_R(x)\equiv B_R(x)Q_R(x) (\mod x^{n-m+1})\)
于是我们求\(B_R(x)\)在\(\mod x^{n-m+1}\)意义下的逆,然后乘以\(A_R(x)\)即可求出\(Q_R(x)\), 从而得到\(Q(x)\).
然后用\(R(x)=A(x)-B(x)Q(x)\)即可求出\(R(x)\).
(虽然算法简单但是要注意的地方还挺多……容易错。)
时间复杂度\(O(n\log n)\), 我写的进行了\(24\)倍常数的ntt.
空间复杂度\(O(n)\), 我的实现好像需要开\(8\)倍。

代码实现

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define llong long long
#define modinc(x) {if(x>=P) x-=P;}
using namespace std;const int N = 1<<19;
const int LGN = 19;
const llong G = 3ll;
const int P = 998244353;
llong tmp1[N+3],tmp2[N+3],tmp3[N+3],tmp4[N+3];
llong tmp5[N+3],tmp6[N+3],tmp7[N+3],tmp8[N+3],tmp9[N+3];
llong a[N+3],b[N+3],q[N+3],r[N+3];
int id[N+3];
int n,m;llong quickpow(llong x,llong y)
{llong cur = x,ret = 1ll;for(int i=0; y; i++){if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur%P;}cur = cur*cur%P;}return ret;
}
llong mulinv(llong x) {return quickpow(x,P-2)%P;}void initid(int dgr)
{int len = 0; for(int i=0; i<=LGN; i++) if((1<<i)==dgr) {len = i; break;}id[0] = 0;for(int i=1; i<dgr; i++) id[i] = (id[i>>1]>>1)|(i&1)<<(len-1);
}int getdgr(int x)
{int ret = 1;while(ret<=x) ret<<=1;return ret;
}void ntt(int dgr,int coe,llong poly[],llong ret[])
{initid(dgr);for(int i=0; i<dgr; i++) ret[i] = poly[i];for(int i=0; i<dgr; i++) if(i<id[i]) swap(ret[i],ret[id[i]]);for(int i=1; i<=(dgr>>1); i<<=1){llong tmp = quickpow(G,(P-1)/(i<<1));if(coe==-1) tmp = mulinv(tmp);for(int j=0; j<dgr; j+=(i<<1)){llong expn = 1ll;for(int k=0; k<i; k++){llong x = ret[j+k],y = ret[j+i+k]*expn%P;ret[j+k] = x+y; modinc(ret[j+k]);ret[j+i+k] = x-y+P; modinc(ret[j+i+k]);expn = (expn*tmp)%P;}}}if(coe==-1){llong tmp = mulinv(dgr);for(int j=0; j<dgr; j++) ret[j] = ret[j]*tmp%P;}
}void polyinv(int dgr,llong poly[],llong ret[])
{for(int i=0; i<dgr; i++) ret[i] = 0ll;ret[0] = mulinv(poly[0]);for(int i=1; i<=(dgr>>1); i<<=1){for(int j=0; j<(i<<2); j++) tmp1[j] = j<i ? ret[j] : 0ll;for(int j=0; j<(i<<2); j++) tmp2[j] = j<(i<<1) ? poly[j] : 0ll;ntt((i<<2),1,tmp1,tmp3); ntt((i<<2),1,tmp2,tmp4);for(int j=0; j<(i<<2); j++) tmp3[j] = tmp3[j]*tmp3[j]%P*tmp4[j]%P;ntt((i<<2),-1,tmp3,tmp4);for(int j=0; j<(i<<1); j++) ret[j] = (tmp1[j]+tmp1[j]-tmp4[j]+P)%P; }for(int j=dgr; j<(dgr<<1); j++) ret[j] = 0ll;
}void polyrev(int dgr,llong poly[],llong ret[])
{for(int i=0; i<dgr; i++) ret[i] = poly[dgr-1-i];
}void polydiv(int dgr1,int dgr2,llong poly1[],llong poly2[],llong ret1[],llong ret2[])
{int _dgr1 = getdgr(dgr1),_dgr2 = getdgr(dgr2);polyrev(dgr2,poly2,tmp5); polyrev(dgr1,poly1,tmp9);polyinv(_dgr1,tmp5,tmp6);for(int i=dgr1-dgr2+1; i<(_dgr1<<1); i++) tmp6[i] = 0ll;ntt(_dgr1<<1,1,tmp9,tmp7); ntt(_dgr1<<1,1,tmp6,tmp8);for(int i=0; i<(_dgr1<<1); i++) tmp7[i] = tmp7[i]*tmp8[i]%P;ntt(_dgr1<<1,-1,tmp7,tmp8);for(int i=dgr1-dgr2+1; i<(_dgr1<<1); i++) tmp8[i] = 0ll;polyrev(dgr1-dgr2+1,tmp8,ret1);ntt(_dgr1<<1,1,poly2,tmp7); ntt(_dgr1<<1,1,ret1,tmp8);for(int i=0; i<(_dgr1<<1); i++) tmp7[i] = tmp7[i]*tmp8[i]%P;ntt(_dgr1<<1,-1,tmp7,ret2);for(int i=dgr2; i<(_dgr1<<1); i++) ret2[i] = 0ll;for(int i=0; i<dgr2-1; i++) ret2[i] = (poly1[i]-ret2[i]+P)%P;
}int main()
{scanf("%d%d",&n,&m); n++; m++;for(int i=0; i<n; i++) scanf("%lld",&a[i]);for(int i=0; i<m; i++) scanf("%lld",&b[i]);int dgr1 = getdgr(n),dgr2 = getdgr(m);polydiv(n,m,a,b,q,r);for(int i=0; i<=n-m; i++) printf("%lld ",q[i]); puts("");for(int i=0; i<m-1; i++) printf("%lld ",r[i]);return 0;
}

发表于 2019-01-23 20:23 suncongbo 阅读(...) 评论(...) 编辑 收藏

刷新评论刷新页面返回顶部

luogu P4512 多项式除法 (模板题、FFT、多项式求逆)相关推荐

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

    luogu P4726 多项式指数函数(模板题FFT.多项式求逆.多项式对数函数) 手动博客搬家: 本文发表于20181127 08:39:42, 原地址https://blog.csdn.net/s ...

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

    luogu P4725 多项式对数函数 (模板题.FFT.多项式求逆.求导和积分) 手动博客搬家: 本文发表于20181125 13:25:03, 原地址https://blog.csdn.net/s ...

  3. python定义多项式除法_python如何进行多项式的加减乘除

    如何进行多项式的加减乘除?这个题目太大! 12个字,写出来很简单,答案却是初中教材上好几章的内容啊,这里不可能详细回答, 也只能给你简单的回答(更详细的,相关概念,更多的题目的例子及方法,请参看教材, ...

  4. 多项式牛顿迭代(应用:求逆,开根,对数exp)

    多项式牛顿迭代 给定多项式g(x)g(x)g(x),求f(x)f(x)f(x),满足g(f(x))≡0(modxn)g(f(x)) \equiv 0 \pmod {x ^ n}g(f(x))≡0(mo ...

  5. 模板——树状数组求逆序对

    题目链接:https://www.luogu.org/problemnew/show/P1908 1 #include <map> 2 #include <set> 3 #in ...

  6. matlab矩阵除法、左除、求逆,这三者有什么区别

    Matlab提供了两种除法运算:左除(\)和右除(/). 一般情况下,x=a\b是方程a*x =b的解,而x=b/a是方程x*a=b的解. 例:a=[1  2  3; 4  2  6;7  4  9] ...

  7. 多项式除法Java实现

    ​​​​​​​ 单项式实体类 例如:在中,代表一个 PolynomialEntity 类对象 /*** 多项式中表示每一项的实体类* 例如:2x^2+1 中,2x^2代表一个 PolynomialEn ...

  8. ~~朴素dijkstra算法 (搜索与图论)(附模板题AcWing 849. Dijkstra求最短路 I)

    模板 时间复杂是 O(n2+m), n表示点数,m 表示边数 int g[N][N]; // 存储每条边 int dist[N]; // 存储1号点到每个点的最短距离 bool st[N]; // 存 ...

  9. luogu P4238 多项式求逆 (模板题、FFT)

    luogu P4238 多项式求逆 (模板题.FFT) 手动博客搬家: 本文发表于20181125 13:21:46, 原地址https://blog.csdn.net/suncongbo/artic ...

最新文章

  1. apache本地配置多域名(wampserver本地配置多域名)
  2. 科学计算机乱码,谁知道我的科学计算器这是怎么了?屏幕一堆乱码,什么都按不了...
  3. 软件测试作业3:软件测试的16条公理
  4. Zookeeper概述、特点、数据模型
  5. LESS vs SASS?选择哪种CSS样式编程语言?
  6. SpringCloud系列-Ribbon的基本应用
  7. 在cmakelists和makefile中设置opencv
  8. 《树莓派Python编程入门与实战(第2版)》——2.2 使用Raspbian命令行
  9. JAVA简历1到三年
  10. keil4与proteus的联调
  11. 呼吸机吸气触发:压力触发与流量触发
  12. uniapp调起打印机(调起第三方打印软件)适用app,将页面生成图片打印的两种方式
  13. 站内优化第二篇:XML 站点地图的全面解析
  14. python编写年金现值计算函数_Python基础(三) 汇率计算demo
  15. Iterative Reweighted Least Squares(IRLS)
  16. 小品《生活不止眼前的苟且》剧本
  17. SAP工具箱 数据同步平台(九 与PO整合)
  18. 微策略2017年秋招线下笔试+技术面+在线测评+主管面总结
  19. java拆分list_Java 8 stream 流 拆分list
  20. 保留指定小数位数js函数封装

热门文章

  1. 5 Android数据存储 任务二 应用程序数据文件夹里的文件读写 ,
  2. 【完结篇】专栏 | 基于 Jupyter 的特征工程手册:特征降维
  3. 专栏 | 基于 Jupyter 的特征工程手册:特征选择(二)
  4. explicit构造函数
  5. matlab 读取含有文本的txt
  6. 在C#中利用Keep-Alive处理Socket网络异常断开的方法
  7. log4net在winform中release后不工作的原因
  8. 数据可视化组队学习:《Task06 - 场景案例显神通》笔记
  9. eclipse导入Java文件后出现中文乱码
  10. Eclipse中自定义注释