首页 > 代码库 > bzoj2194: 快速傅立叶之二
bzoj2194: 快速傅立叶之二
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 const int maxn=400005; 8 const double PI=acos(-1); 9 struct node{10 double real,imag;11 void clear(){real=imag=0;}12 node operator +(const node &x){return (node){real+x.real,imag+x.imag};}13 node operator -(const node &x){return (node){real-x.real,imag-x.imag};}14 node operator *(const node &x){return (node){real*x.real-imag*x.imag,real*x.imag+imag*x.real};}15 }a[maxn],b[maxn],c[maxn],t1,t2,w,wn;16 int m,n,len,rev[maxn],ans[maxn];17 void read(int &x){18 x=0; int f=1; char ch;19 for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch==‘-‘) f=-1;20 for (;isdigit(ch);ch=getchar()) x=x*10+ch-‘0‘; x*=f;21 }22 int Rev(int x){23 int temp=0;24 for (int i=1;i<=len;i++) temp<<=1,temp+=(x&1),x>>=1;25 return temp;26 }27 void FFT(node *a,int op){28 for (int i=0;i<n;i++) if (i<rev[i]) swap(a[i],a[rev[i]]);29 for (int s=2;s<=n;s<<=1){30 wn=(node){cos(2*op*PI/s),sin(2*op*PI/s)};31 for (int i=0;i<n;i+=s){32 w=(node){1,0};33 for (int j=i;j<i+s/2;j++,w=w*wn){34 t1=a[j],t2=w*a[j+s/2];35 a[j]=t1+t2,a[j+s/2]=t1-t2;36 }37 }38 }39 }40 int main(){41 read(m); n=1,len=0;42 while (n<(m<<1)) n<<=1,len++;43 for (int i=0;i<n;i++) rev[i]=Rev(i);44 for (int x,i=0;i<m;i++) read(x),a[i].real=x,read(x),b[m-1-i].real=x;45 FFT(a,1),FFT(b,1);46 for (int i=0;i<n;i++) c[i]=a[i]*b[i];47 FFT(c,-1);48 for (int i=0;i<n;i++) ans[i]=(int)round(c[i].real/n);49 for (int i=m-1;i<2*m-1;i++) printf("%d\n",ans[i]);50 return 0;51 }
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2194
题目大意:请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5。 a,b中的元素均为小于等于100的非负整数。
做法:考虑把b数组翻转,Ck的计算就成为了裸的卷积,对于这种题目,翻转是个重要的手段。
bzoj2194: 快速傅立叶之二
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。