1. 程式人生 > >2019.01.02 洛谷P4512 【模板】多項式除法

2019.01.02 洛谷P4512 【模板】多項式除法

傳送門
解析
程式碼:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
#define add(a,b) ((a)+(b)>=mod?(a)+(b)-mod:(a)+(b))
#define dec(a,b) ((a)>=(b)?(a)-(b):(a)-(b)+mod)
#define mul(a,b) ((ll)(a)*(b)%mod)
inline int read(){
	int ans=0;
	char ch=getchar
(); while(!isdigit(ch))ch=getchar(); while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar(); return ans; } const int mod=998244353; int lim,tim; vector<int>pos,A,B; inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)ret=mul(ret,a);return ret;} inline
void init(const int&up){ lim=1,tim=0; while(lim<=up)lim<<=1,++tim; pos.resize(lim),pos[0]=0; for(ri i=0;i<lim;++i)pos[i]=(pos[i>>1]>>1)|((i&1)<<(tim-1)); } inline void ntt(vector<int>&a,const int&type){ for(ri i=0;i<lim;++i)if(i<pos[i])swap(
a[i],a[pos[i]]); for(ri mid=1,wn,typ=type==1?3:(mod+1)/3,mult=(mod-1)/2;mid<lim;mid<<=1,mult>>=1){ wn=ksm(typ,mult); for(ri j=0,len=mid<<1;j<lim;j+=len)for(ri k=0,a0,a1,w=1;k<mid;++k,w=mul(w,wn)){ a0=a[j+k],a1=mul(w,a[j+k+mid]); a[j+k]=add(a0,a1),a[j+k+mid]=dec(a0,a1); } } if(type==-1)for(ri i=0,inv=ksm(lim,mod-2);i<lim;++i)a[i]=mul(a[i],inv); } struct poly{ vector<int>a; poly(int k,int x=0){a.resize(k+1),a[k]=x;} inline int&operator[](const int&k){return a[k];} inline const int&operator[](const int&k)const{return a[k];} inline int deg()const{return a.size()-1;} inline poly extend(const int&k){poly ret=*this;return ret.a.resize(k+1),ret;} friend inline poly operator+(const poly&a,const poly&b){ poly ret(max(a.deg(),b.deg())); for(ri i=0;i<=a.deg();++i)ret[i]=add(ret[i],a[i]); for(ri i=0;i<=b.deg();++i)ret[i]=add(ret[i],b[i]); return ret; } friend inline poly operator-(const poly&a,const poly&b){ poly ret(max(a.deg(),b.deg())); for(ri i=0;i<=a.deg();++i)ret[i]=add(ret[i],a[i]); for(ri i=0;i<=b.deg();++i)ret[i]=dec(ret[i],b[i]); return ret; } friend inline poly operator*(const int&a,const poly&b){ poly ret(b.deg()); for(ri i=0;i<=b.deg();++i)ret[i]=mul(a,b[i]); return ret; } friend inline poly operator*(const poly&a,const poly&b){ int n=a.deg(),m=b.deg(); init(n+m),A.resize(lim),B.resize(lim); poly ret(lim-1); for(ri i=0;i<=n;++i)A[i]=a[i]; for(ri i=0;i<=m;++i)B[i]=b[i]; for(ri i=n+1;i<lim;++i)A[i]=0; for(ri i=m+1;i<lim;++i)B[i]=0; ntt(A,1),ntt(B,1); for(ri i=0;i<lim;++i)A[i]=mul(A[i],B[i]); return ntt(A,-1),ret.a=A,ret; } inline poly poly_inv(poly a,const int&k){ if(k==1)return poly(0,ksm(a[0],mod-2)); a=a.extend(k); poly f0=poly_inv(a,(k+1)>>1); return (2*f0-((f0*f0).extend(k)*a).extend(k)).extend(k); } friend inline poly operator/(const poly&a,const poly&b){ poly ta=a,tb=b; int len=1,up=a.deg()-b.deg(); reverse(ta.a.begin(),ta.a.end()),reverse(tb.a.begin(),tb.a.end()); ta.extend(up),tb.extend(up); while(len<=up)len<<=1; tb=tb.poly_inv(tb,len).extend(up); return ta=(ta*tb).extend(up),reverse(ta.a.begin(),ta.a.end()),ta; } }; int n,m; int main(){ n=read(),m=read(); poly a(n),b(m),ans(n-m); for(ri i=0;i<=n;++i)a[i]=read(); for(ri i=0;i<=m;++i)b[i]=read(); ans=a/b; for(ri i=0;i<=n-m;++i)cout<<ans[i]<<' '; puts(""),ans=a-ans*b; for(ri i=0;i<m;++i)cout<<ans[i]<<' '; return 0; }