萌新刚学OI,不是妹子,这题挂了

P4512 【模板】多项式除法

@[Simpson561](/space/show?uid=53034) NTT里面bit没用啊,还有就是为什么那么多1<<mid,1<<(mid+1),写的不难受吗qwq。关于tmp完全可以预处理出来而不是每次算一下啊。Mul里面长度是$Len_F+Len_G-1$(这个没多大影响)。
by ecnerwaIa @ 2019-05-23 08:21:53


@[Simpson561](/space/show?uid=53034) 第129行改成从$Len_F-Len_G+1$开始。
by ecnerwaIa @ 2019-05-23 08:27:57


@[Simpson561](/space/show?uid=53034) 还有就是最后一个Mul,F,G后半部分没有全部清空
by ecnerwaIa @ 2019-05-23 08:46:15


@[Simpson561](/space/show?uid=53034) ```cpp #include <bits/stdc++.h> using namespace std; #define int long long const int MOD=998244353,g=3; const int MAXLEN=1<<23|1; int N,M,F[MAXLEN],G[MAXLEN],ans[MAXLEN];//basic int lim=1,lg=0,tmp[109],rev[MAXLEN];//NTT int C[MAXLEN];//Inv int Gr[MAXLEN],_Gr[MAXLEN],Q[MAXLEN],R[MAXLEN];//Devide namespace IO { const int BUF_SIZE=1<<15; char in_buf[BUF_SIZE],out_buf[BUF_SIZE]; char *p_in_buf=in_buf+BUF_SIZE; char *p_out_buf=out_buf; inline char get_char() { if(p_in_buf==in_buf+BUF_SIZE) fread(in_buf,1,BUF_SIZE,stdin),p_in_buf=in_buf; return *(p_in_buf++); } inline void put_char(char x) { if(p_out_buf==out_buf+BUF_SIZE) fwrite(out_buf,1,BUF_SIZE,stdout),p_out_buf=out_buf; *(p_out_buf++)=x; } inline void flush() { if(p_out_buf!=out_buf) fwrite(out_buf,1,p_out_buf-out_buf,stdout),p_out_buf=out_buf; } // #define getchar() IO::get_char() // #define putchar(x) IO::put_char(x) inline int getint() { int x=0; char c=getchar(); while(c<=32) c=getchar(); while(c>32) x=x*10+(c&15),c=getchar(); return x; } inline int getint(char &c) { int x=0; c=getchar(); while(c<=32) c=getchar(); while(c>32) x=x*10+(c&15),c=getchar(); return x; } template <class T> inline void _putint(T x) { return x?_putint(x/10), putchar((x%10)|48),void():void(); } template <class T> inline void putint(T x) { return x==0?putchar('0'),void():_putint(x),void(); } inline void getline(char *s) { char c=getchar(); while(c=='\n') c=getchar(); while(c!='\n') *(s++)=c,c=getchar(); *s=0; } } using namespace IO; inline void _swap(int &a,int &b) { int _=a; a=b,b=_; } inline int quickpower(int a,int n,int m) { int i,s; for(i=a,s=1;n;n>>=1,i=i*i%m) if(n&1) s=s*i%m; return s; } inline void init(int len_sum) { lim=1,lg=0; while(lim<=len_sum) lim<<=1,lg++; for(register int i=1;i<=lim;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)); for(register int mid=0;(1<<mid)<lim;mid++) tmp[mid]=quickpower(g,(MOD-1)>>(mid+1),MOD); } inline void NTT(int *F,const int len,const int inv_flg) { register int i,j,step,s,enk,wn,x,now,inv=quickpower(len,MOD-2,MOD); for(i=0;i<len;i++) if(i<rev[i]) _swap(F[i],F[rev[i]]); for(step=1,s=2,now=0;step<len;step<<=1,s<<=1,++now){ enk=tmp[now]; for(i=0;i<len;i+=s){ wn=1; for(j=i;j<i+step;++j){ x=F[j+step]*wn%MOD; F[j+step]=(F[j]-x+MOD)%MOD; F[j]=(F[j]+x)%MOD; wn=wn*enk%MOD; } } } if(inv_flg==-1) { reverse(F+1,F+len); for(int i=0;i<len;i++) F[i]=F[i]*inv%MOD; } } inline void Mul(int len_F,int len_G,int *F,int *G,int *Ans) { init(len_F+len_G-1); memset(F+(lim>>1),0,lim<<2); memset(G+(lim>>1),0,lim<<2); NTT(F,lim,1),NTT(G,lim,1); for(register int i=0;i<lim;i++) Ans[i]=F[i]*G[i]%MOD; NTT(Ans,lim,-1); } inline void Inv(int len,int *F,int *Ans) { if(len==1) {Ans[0]=quickpower(F[0],MOD-2,MOD); return;} Inv((len+1)>>1,F,Ans); for(register int i=0;i<len;i++) C[i]=F[i]; for(register int i=len;i<lim;i++) C[i]=0; init(len<<1); NTT(C,lim,1),NTT(Ans,lim,1); for(register int i=0;i<lim;i++) Ans[i]=(2-C[i]*Ans[i]%MOD+MOD)%MOD*Ans[i]%MOD; NTT(Ans,lim,-1); for(register int i=len;i<lim;i++) Ans[i]=0; } inline void Divide(int len_F,int len_G,int *F,int *G,int *Q,int *R) { for(register int i=0;i<=len_F;i++) Q[len_F-i]=F[i]; for(register int i=0;i<=len_G;i++) Gr[len_G-i]=G[i]; for(register int i=len_F-len_G+1;i<=len_G;i++) Gr[i]=0; Inv(len_F-len_G+1,Gr,_Gr); for(register int i=0;i<=len_F-len_G;i++) Gr[i]=_Gr[i]; Mul(len_F-len_G+1,len_F-len_G+1,Q,Gr,Q); reverse(Q,Q+len_F-len_G+1); for(register int i=len_F-len_G+1;i<=len_F;i++) Q[i]=0; Mul(len_F-len_G+1,len_G+1,Q,G,R); for(register int i=0;i<=len_G-1;i++) R[i]=(F[i]-R[i]+MOD)%MOD; NTT(Q,lim,-1); } signed main() { N=getint(),M=getint(); for(int i=0;i<=N;i++) F[i]=getint(); for(int i=0;i<=M;i++) G[i]=getint(); Divide(N,M,F,G,Q,R); for(int i=0;i<=N-M;i++) putint(Q[i]),putchar(' '); putchar('\n'); for(int i=0;i<=M-1;i++) putint(R[i]),putchar(' '); flush(); return 0; } ``` 这是修改完的兄弟,累死我了。
by ecnerwaIa @ 2019-05-23 08:49:37


@[Simpson561](/space/show?uid=53034) ```cpp #include <bits/stdc++.h> using namespace std; #define int long long const int MOD=998244353,g=3; const int MAXLEN=1<<23|1; int N,M,F[MAXLEN],G[MAXLEN],ans[MAXLEN];//basic int lim=1,lg=0,tmp[109],rev[MAXLEN];//NTT int C[MAXLEN];//Inv int Gr[MAXLEN],_Gr[MAXLEN],Q[MAXLEN],R[MAXLEN];//Devide namespace IO { const int BUF_SIZE=1<<15; char in_buf[BUF_SIZE],out_buf[BUF_SIZE]; char *p_in_buf=in_buf+BUF_SIZE; char *p_out_buf=out_buf; inline char get_char() { if(p_in_buf==in_buf+BUF_SIZE) fread(in_buf,1,BUF_SIZE,stdin),p_in_buf=in_buf; return *(p_in_buf++); } inline void put_char(char x) { if(p_out_buf==out_buf+BUF_SIZE) fwrite(out_buf,1,BUF_SIZE,stdout),p_out_buf=out_buf; *(p_out_buf++)=x; } inline void flush() { if(p_out_buf!=out_buf) fwrite(out_buf,1,p_out_buf-out_buf,stdout),p_out_buf=out_buf; } // #define getchar() IO::get_char() // #define putchar(x) IO::put_char(x) inline int getint() { int x=0; char c=getchar(); while(c<=32) c=getchar(); while(c>32) x=x*10+(c&15),c=getchar(); return x; } inline int getint(char &c) { int x=0; c=getchar(); while(c<=32) c=getchar(); while(c>32) x=x*10+(c&15),c=getchar(); return x; } template <class T> inline void _putint(T x) { return x?_putint(x/10), putchar((x%10)|48),void():void(); } template <class T> inline void putint(T x) { return x==0?putchar('0'),void():_putint(x),void(); } inline void getline(char *s) { char c=getchar(); while(c=='\n') c=getchar(); while(c!='\n') *(s++)=c,c=getchar(); *s=0; } } using namespace IO; inline void _swap(int &a,int &b) { int _=a; a=b,b=_; } inline int quickpower(int a,int n,int m) { int i,s; for(i=a,s=1;n;n>>=1,i=i*i%m) if(n&1) s=s*i%m; return s; } inline void init(int len_sum) { lim=1,lg=0; while(lim<=len_sum) lim<<=1,lg++; for(register int i=1;i<=lim;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)); for(register int mid=0;(1<<mid)<lim;mid++) tmp[mid]=quickpower(g,(MOD-1)>>(mid+1),MOD); } inline void NTT(int *F,const int len,const int inv_flg) { register int i,j,step,s,enk,wn,x,now,inv=quickpower(len,MOD-2,MOD); for(i=0;i<len;i++) if(i<rev[i]) _swap(F[i],F[rev[i]]); for(step=1,s=2,now=0;step<len;step<<=1,s<<=1,++now){ enk=tmp[now]; for(i=0;i<len;i+=s){ wn=1; for(j=i;j<i+step;++j){ x=F[j+step]*wn%MOD; F[j+step]=(F[j]-x+MOD)%MOD; F[j]=(F[j]+x)%MOD; wn=wn*enk%MOD; } } } if(inv_flg==-1) { reverse(F+1,F+len); for(int i=0;i<len;i++) F[i]=F[i]*inv%MOD; } } inline void Mul(int len_F,int len_G,int *F,int *G,int *Ans) { init(len_F+len_G-1); memset(F+(lim>>1),0,lim<<2); memset(G+(lim>>1),0,lim<<2); NTT(F,lim,1),NTT(G,lim,1); for(register int i=0;i<lim;i++) Ans[i]=F[i]*G[i]%MOD; NTT(Ans,lim,-1); } inline void Inv(int len,int *F,int *Ans) { if(len==1) {Ans[0]=quickpower(F[0],MOD-2,MOD); return;} Inv((len+1)>>1,F,Ans); for(register int i=0;i<len;i++) C[i]=F[i]; for(register int i=len;i<lim;i++) C[i]=0; init(len<<1); NTT(C,lim,1),NTT(Ans,lim,1); for(register int i=0;i<lim;i++) Ans[i]=(2-C[i]*Ans[i]%MOD+MOD)%MOD*Ans[i]%MOD; NTT(Ans,lim,-1); for(register int i=len;i<lim;i++) Ans[i]=0; } inline void Divide(int len_F,int len_G,int *F,int *G,int *Q,int *R) { for(register int i=0;i<=len_F;i++) Q[len_F-i]=F[i]; for(register int i=0;i<=len_G;i++) Gr[len_G-i]=G[i]; for(register int i=len_F-len_G+1;i<=len_G;i++) Gr[i]=0; Inv(len_F-len_G+1,Gr,_Gr); for(register int i=0;i<=len_F-len_G;i++) Gr[i]=_Gr[i]; Mul(len_F-len_G+1,len_F-len_G+1,Q,Gr,Q); reverse(Q,Q+len_F-len_G+1); for(register int i=len_F-len_G+1;i<=len_F;i++) Q[i]=0; Mul(len_F-len_G+1,len_G+1,Q,G,R); for(register int i=0;i<=len_G-1;i++) R[i]=(F[i]-R[i]+MOD)%MOD; NTT(Q,lim,-1); } signed main() { N=getint(),M=getint(); for(int i=0;i<=N;i++) F[i]=getint(); for(int i=0;i<=M;i++) G[i]=getint(); Divide(N,M,F,G,Q,R); for(int i=0;i<=N-M;i++) putint(Q[i]),putchar(' '); putchar('\n'); for(int i=0;i<=M-1;i++) putint(R[i]),putchar(' '); flush(); return 0; } ```
by ecnerwaIa @ 2019-05-23 08:49:54


@[Simpson561](/space/show?uid=53034) 哦,有个地方写错了qwq
by ecnerwaIa @ 2019-05-23 08:51:33


@[Simpson561](/space/show?uid=53034) ```cpp #include <bits/stdc++.h> using namespace std; #define int long long const int MOD=998244353,g=3; const int MAXLEN=1<<23|1; int N,M,F[MAXLEN],G[MAXLEN],ans[MAXLEN];//basic int lim=1,lg=0,tmp[109],rev[MAXLEN];//NTT int C[MAXLEN];//Inv int Gr[MAXLEN],_Gr[MAXLEN],Q[MAXLEN],R[MAXLEN];//Devide namespace IO { const int BUF_SIZE=1<<15; char in_buf[BUF_SIZE],out_buf[BUF_SIZE]; char *p_in_buf=in_buf+BUF_SIZE; char *p_out_buf=out_buf; inline char get_char() { if(p_in_buf==in_buf+BUF_SIZE) fread(in_buf,1,BUF_SIZE,stdin),p_in_buf=in_buf; return *(p_in_buf++); } inline void put_char(char x) { if(p_out_buf==out_buf+BUF_SIZE) fwrite(out_buf,1,BUF_SIZE,stdout),p_out_buf=out_buf; *(p_out_buf++)=x; } inline void flush() { if(p_out_buf!=out_buf) fwrite(out_buf,1,p_out_buf-out_buf,stdout),p_out_buf=out_buf; } // #define getchar() IO::get_char() // #define putchar(x) IO::put_char(x) inline int getint() { int x=0; char c=getchar(); while(c<=32) c=getchar(); while(c>32) x=x*10+(c&15),c=getchar(); return x; } inline int getint(char &c) { int x=0; c=getchar(); while(c<=32) c=getchar(); while(c>32) x=x*10+(c&15),c=getchar(); return x; } template <class T> inline void _putint(T x) { return x?_putint(x/10), putchar((x%10)|48),void():void(); } template <class T> inline void putint(T x) { return x==0?putchar('0'),void():_putint(x),void(); } inline void getline(char *s) { char c=getchar(); while(c=='\n') c=getchar(); while(c!='\n') *(s++)=c,c=getchar(); *s=0; } } using namespace IO; inline void _swap(int &a,int &b) { int _=a; a=b,b=_; } inline int quickpower(int a,int n,int m) { int i,s; for(i=a,s=1;n;n>>=1,i=i*i%m) if(n&1) s=s*i%m; return s; } inline void init(int len_sum) { lim=1,lg=0; while(lim<=len_sum) lim<<=1,lg++; for(register int i=1;i<=lim;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)); for(register int mid=0;(1<<mid)<lim;mid++) tmp[mid]=quickpower(g,(MOD-1)>>(mid+1),MOD); } inline void NTT(int *F,const int len,const int inv_flg) { register int i,j,step,s,enk,wn,x,now,inv=quickpower(len,MOD-2,MOD); for(i=0;i<len;i++) if(i<rev[i]) _swap(F[i],F[rev[i]]); for(step=1,s=2,now=0;step<len;step<<=1,s<<=1,++now){ enk=tmp[now]; for(i=0;i<len;i+=s){ wn=1; for(j=i;j<i+step;++j){ x=F[j+step]*wn%MOD; F[j+step]=(F[j]-x+MOD)%MOD; F[j]=(F[j]+x)%MOD; wn=wn*enk%MOD; } } } if(inv_flg==-1) { reverse(F+1,F+len); for(int i=0;i<len;i++) F[i]=F[i]*inv%MOD; } } inline void Mul(int len_F,int len_G,int *F,int *G,int *Ans) { init(len_F+len_G-1); memset(F+len_F,0,(lim-len_F)<<3); memset(G+len_G,0,(lim-len_G)<<3); NTT(F,lim,1),NTT(G,lim,1); for(register int i=0;i<lim;i++) Ans[i]=F[i]*G[i]%MOD; NTT(Ans,lim,-1); } inline void Inv(int len,int *F,int *Ans) { if(len==1) {Ans[0]=quickpower(F[0],MOD-2,MOD); return;} Inv((len+1)>>1,F,Ans); for(register int i=0;i<len;i++) C[i]=F[i]; for(register int i=len;i<lim;i++) C[i]=0; init(len<<1); NTT(C,lim,1),NTT(Ans,lim,1); for(register int i=0;i<lim;i++) Ans[i]=(2-C[i]*Ans[i]%MOD+MOD)%MOD*Ans[i]%MOD; NTT(Ans,lim,-1); for(register int i=len;i<lim;i++) Ans[i]=0; } inline void Divide(int len_F,int len_G,int *F,int *G,int *Q,int *R) { for(register int i=0;i<=len_F;i++) Q[len_F-i]=F[i]; for(register int i=0;i<=len_G;i++) Gr[len_G-i]=G[i]; for(register int i=len_F-len_G+1;i<=len_G;i++) Gr[i]=0; Inv(len_F-len_G+1,Gr,_Gr); for(register int i=0;i<=len_F-len_G;i++) Gr[i]=_Gr[i]; Mul(len_F-len_G+1,len_F-len_G+1,Q,Gr,Q); reverse(Q,Q+len_F-len_G+1); for(register int i=len_F-len_G+1;i<=len_F;i++) Q[i]=0; for(int i=0;i<=len_F-len_G;++i)putint(Q[i]),putchar(' '); putchar('\n'); Mul(len_F-len_G+1,len_G+1,Q,G,R); for(register int i=0;i<=len_G-1;i++) R[i]=(F[i]-R[i]+MOD)%MOD; } signed main() { // freopen("0.in","r",stdin); N=getint(),M=getint(); for(int i=0;i<=N;i++) F[i]=getint(); for(int i=0;i<=M;i++) G[i]=getint(); Divide(N,M,F,G,Q,R); for(int i=0;i<=M-1;i++) putint(R[i]),putchar(' '); flush(); return 0; } ``` 通过代码。不懂的地方可以来问我
by ecnerwaIa @ 2019-05-23 09:00:47


@[千年之狐_天才](/space/show?uid=54113) 谢谢大佬%%%
by Simpson561 @ 2019-05-23 12:15:44


上一页 |