博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P5205 【模板】多项式开根(FFT)
阅读量:4992 次
发布时间:2019-06-12

本文共 2816 字,大约阅读时间需要 9 分钟。

题面

题解

考虑分治

假设我们已经求出\(A'^2\equiv B\pmod{x^n}\),考虑如何计算出\(A^2\equiv B\pmod{x^{2n}}\)

首先肯定存在\(A^2\equiv B\pmod{x^n}\)

然后两式相减\[A'^2-A^2\equiv 0\pmod{x^n}\]

\[(A'-A)(A'+A)\equiv 0\pmod{x^n}\]

我们假设\(A'-A\equiv 0\pmod{x^n}\),然后两边平方\[A'^2-2A'A+A^2\equiv 0\pmod{x^{2n}}\]

(关于平方之后模数变化的原因可以看我多项式求逆那篇文章,里面有写)

又因为\(A^2\equiv B\pmod{x^{2n}}\),代入得\[A'^2-2A'A+B\equiv 0\pmod{x^{2n}}\]

\[A\equiv\frac{A'^2+B}{2A'}\pmod{x^{2n}}\]

//minamoto#include
#define R register#define fp(i,a,b) for(R int i=(a),I=(b)+1;i
I;--i)#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)using namespace std;char buf[1<<21],*p1=buf,*p2=buf;inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}int read(){ R int res,f=1;R char ch; while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1); for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0'); return res*f;}char sr[1<<21],z[20];int C=-1,Z=0;inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}void print(R int x){ if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x; while(z[++Z]=x%10+48,x/=10); while(sr[++C]=z[Z],--Z);sr[++C]=' ';}const int N=(1<<18)+5,P=998244353,Gi=332748118,inv2=499122177;inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}int ksm(R int x,R int y){ R int res=1; for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x); return res;}int r[19][N],rt[2][N<<1],lim,d;void Pre(){ fp(d,1,18)fp(i,1,(1<
>1]>>1)|((i&1)<<(d-1)); for(R int t=(P-1)>>1,i=1,x,y;i<=262144;i<<=1,t>>=1){ x=ksm(3,t),y=ksm(Gi,t),rt[0][i]=rt[1][i]=1; fp(k,1,i-1) rt[1][i+k]=mul(rt[1][i+k-1],x), rt[0][i+k]=mul(rt[0][i+k-1],y); }}inline void init(R int len){lim=1,d=0;while(lim
<<=1,++d;}void NTT(int *A,int ty){ fp(i,0,lim-1)if(i
>1); static int A[N],B[N];init(len<<1); fp(i,0,len-1)A[i]=a[i],B[i]=b[i]; fp(i,len,lim-1)A[i]=B[i]=0; NTT(A,1),NTT(B,1); fp(i,0,lim-1)A[i]=mul(A[i],mul(B[i],B[i])); NTT(A,0); fp(i,0,len-1)b[i]=dec(add(b[i],b[i]),A[i]); fp(i,len,lim-1)b[i]=0;}void Sqrt(int *a,int *b,int len){ if(len==1)return b[0]=1,void(); Sqrt(a,b,len>>1); static int A[N],B[N]; fp(i,0,len-1)A[i]=a[i];Inv(b,B,len); init(len<<1);fp(i,len,lim-1)A[i]=B[i]=0; NTT(A,1),NTT(B,1); fp(i,0,lim-1)A[i]=mul(A[i],B[i]); NTT(A,0); fp(i,0,len-1)b[i]=mul(add(b[i],A[i]),inv2); fp(i,len,lim-1)b[i]=0;}int A[N],B[N],n;int main(){// freopen("testdata.in","r",stdin); Pre(); n=read(); fp(i,0,n-1)A[i]=read(); int len=1;while(len
<<=1; Sqrt(A,B,len); fp(i,0,n-1)print(B[i]); return Ot(),0;}

转载于:https://www.cnblogs.com/bztMinamoto/p/10567954.html

你可能感兴趣的文章
LeetCode - Anagrams
查看>>
用MFC时,如果程序崩溃,检查内存,然后注意GDI数量,在任务管理器里选项-查看列-GDI数量...
查看>>
angular(转)
查看>>
ansible简单现网配置
查看>>
数据结构C++版-树
查看>>
JavaScript学习总结--创建对象(3_原型)
查看>>
FZU 2092 收集水晶 dp+bfs
查看>>
Java学习---网页编辑器FCKeditor使用详解
查看>>
IDEA开发React环境配置
查看>>
香港两日游
查看>>
cordova 打包发布正式版 apk
查看>>
常用集合比较
查看>>
二分搜索
查看>>
感觉这周的每日都是累
查看>>
Tarjan求点双连通分量
查看>>
Tomcat项目自动部署脚本
查看>>
Python操作MySQL数据库
查看>>
自动化部署之jenkins及简介
查看>>
CodeForces 1152D Neko and Aki's Prank
查看>>
Python 用pygame模块播放MP3
查看>>