UOJ 34 多项式乘法(FFT)
2017-08-16 18:41
519 查看
Description
给你两个多项式,请输出乘起来后的多项式
Input
第一行两个整数n和m,分别表示两个多项式的次数
第二行n+1个整数,分别表示第一个多项式的0到n次项前的系数
第三行m+1个整数,分别表示第一个多项式的0到m次项前的系数
Output
一行n+m+1个整数,分别表示乘起来后的多项式的0到n+m次项前的系数
Sample Input
1 2
1 2
1 2 1
Sample Output
1 4 5 2
Solution
FFT模版题
Code
给你两个多项式,请输出乘起来后的多项式
Input
第一行两个整数n和m,分别表示两个多项式的次数
第二行n+1个整数,分别表示第一个多项式的0到n次项前的系数
第三行m+1个整数,分别表示第一个多项式的0到m次项前的系数
Output
一行n+m+1个整数,分别表示乘起来后的多项式的0到n+m次项前的系数
Sample Input
1 2
1 2
1 2 1
Sample Output
1 4 5 2
Solution
FFT模版题
Code
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; namespace fastIO { #define BUF_SIZE 100000 //fread -> read bool IOerror=0; inline char nc() { static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE; if(p1==pend) { p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin); if(pend==p1) { IOerror=1; return -1; } } return *p1++; } inline bool blank(char ch) { return ch==' '||ch=='\n'||ch=='\r'||ch=='\t'; } inline void read(int &x) { char ch; while(blank(ch=nc())); if(IOerror)return; for(x=ch-'0';(ch=nc())>='0'&&ch<='9';x=x*10+ch-'0'); } inline void readc(char &x) { char ch; while(blank(ch=nc())); if(IOerror)return; x=ch; } #undef BUF_SIZE }; using namespace fastIO; #define maxn 131072+5 const double pi=acos(-1.0); struct cp { double a,b; cp operator +(const cp &o)const {return (cp){a+o.a,b+o.b};} cp operator -(const cp &o)const {return (cp){a-o.a,b-o.b};} cp operator *(const cp &o)const {return (cp){a*o.a-b*o.b,b*o.a+a*o.b};} cp operator *(const double &o)const {return (cp){a*o,b*o};} cp operator !() const{return (cp){a,-b};} }w[maxn]; int pos[maxn]; void fft_init(int len) { int j=0; while((1<<j)<len)j++; j--; for(int i=0;i<len;i++) pos[i]=pos[i>>1]>>1|((i&1)<<j); } void fft(cp *x,int len,int sta) { for(int i=0;i<len;i++) if(i<pos[i])swap(x[i],x[pos[i]]); w[0]=(cp){1,0}; for(unsigned i=2;i<=len;i<<=1) { cp g=(cp){cos(2*pi/i),sin(2*pi/i)*sta}; for(int j=i>>1;j>=0;j-=2)w[j]=w[j>>1]; for(int j=1;j<i>>1;j+=2)w[j]=w[j-1]*g; for(int j=0;j<len;j+=i) { cp *a=x+j,*b=a+(i>>1); for(int l=0;l<i>>1;l++) { cp o=b[l]*w[l]; b[l]=a[l]-o; a[l]=a[l]+o; } } } if(sta==-1)for(int i=0;i<len;i++)x[i].a/=len,x[i].b/=len; } cp x[maxn],y[maxn],z[maxn]; void FFT(int *a,int *b,int n,int m,int *c) { if(n<=100&&m<=100||min(n,m)<=5) { for(int i=0;i<n+m;i++)c[i]=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) c[i+j]+=a[i]*b[j]; return ; } for(int i=0;i<n;i++)(i&1?x[i>>1].b:x[i>>1].a)=a[i]; for(int i=0;i<m;i++)(i&1?y[i>>1].b:y[i>>1].a)=b[i]; int len=1; while(len<(n+m)>>1)len<<=1; fft_init(len); fft(x,len,1),fft(y,len,1); for(int i=0;i<len/2;i++) { int j=len-1&len-i; z[i]=x[i]*y[i]-(x[i]-!x[j])*(y[i]-!y[j])*(w[i]+(cp){1,0})*0.25; } for(int i=len/2;i<len;i++) { int j=len-1&len-i; z[i]=x[i]*y[i]-(x[i]-!x[j])*(y[i]-!y[j])*((cp){1,0}-w[i^len>>1])*0.25; } fft(z,len,-1); for(int i=0;i<n+m;i++) if(i&1)c[i]=(int)(z[i>>1].b+0.5); else c[i]=(int)(z[i>>1].a+0.5); } int n,m,a[maxn],b[maxn],c[maxn<<1]; int main() { read(n),read(m); //scanf("%d%d",&n,&m); for(int i=0;i<=n;i++)read(a[i]);//scanf("%d",&a[i]); for(int i=0;i<=m;i++)read(b[i]);//scanf("%d",&b[i]); FFT(a,b,n+1,m+1,c); for(int i=0;i<=n+m;i++)printf("%d%c",c[i],i==n+m?'\n':' '); return 0; }
相关文章推荐
- [uoj 34 多项式乘法] FFT&NTT 模板
- [UOJ#34]多项式乘法(FFT)
- 【FFT优化】[UOJ#34]多项式乘法
- 【UOJ 34】 多项式乘法 (FFT)
- [UOJ#34]多项式乘法(FFT)
- uoj 34 多项式乘法(fft入门)
- FFT uoj34 多项式乘法
- [UOJ 34]多项式乘法(FFT)
- [UOJ34]多项式乘法(快速傅立叶变换FFT)
- 【UOJ 34】 #34. 多项式乘法 (FFT)
- UOJ34 多项式乘法 fft板子
- [省选前题目整理][UOJ 34]多项式乘法(FFT)
- [uoj 34 多项式乘法] FFT&NTT 模板
- UOJ #34 多项式乘法
- UOJ 34 多项式乘法
- UOJ 34 多项式乘法
- UOJ 34 多项式乘法
- 【UOJ 34】多项式乘法
- 【NTT模板】[UOJ#34]多项式乘法
- [UOJ#34]多项式乘法