可以看这位大爷的题解:http://blog.csdn.net/snowy_smile/article/details/52020971
#include<bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #define INFLL 0x3f3f3f3f3f3f3f3f #define FIN freopen("input.txt","r",stdin) #define mem(x,y) memset(x,y,sizeof(x)) typedef unsigned long long ULL; typedef long long LL; #define fuck(x) cout<<"q"<<endl; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef pair<pair<int,int>,int> PIII; typedef pair<int,int> PII; const double eps=1e-6; const int MX=4e5+5; const int P=313; int n; int a[MX]; const double pi = acos(-1.0); int len,mx;//开大4倍 int res[MX]; struct Complex { double r,i; Complex(double r=0,double i=0):r(r),i(i) {}; Complex operator+(const Complex &rhs) { return Complex(r + rhs.r,i + rhs.i); } Complex operator-(const Complex &rhs) { return Complex(r - rhs.r,i - rhs.i); } Complex operator*(const Complex &rhs) { return Complex(r*rhs.r - i*rhs.i,i*rhs.r + r*rhs.i); } } va[MX],vb[MX]; void rader(Complex F[],int len) //len = 2^M,reverse F[i] with F[j] j为i二进制反转 { int j = len >> 1; for(int i = 1; i < len - 1; ++i) { if(i < j) swap(F[i],F[j]); // reverse int k = len>>1; while(j>=k) { j -= k; k >>= 1; } if(j < k) j += k; } } void FFT(Complex F[],int len,int t) { rader(F,len); for(int h=2; h<=len; h<<=1) { Complex wn(cos(-t*2*pi/h),sin(-t*2*pi/h)); for(int j=0; j<len; j+=h) { Complex E(1,0); //旋转因子 for(int k=j; k<j+h/2; ++k) { Complex u = F[k]; Complex v = E*F[k+h/2]; F[k] = u+v; F[k+h/2] = u-v; E=E*wn; } } } if(t==-1) //IDFT for(int i=0; i<len; ++i) F[i].r/=len; } void Conv(Complex a[],Complex b[],int len) //求卷积 { FFT(a,len,1); FFT(b,1); for(int i=0; i<len; ++i) a[i] = a[i]*b[i]; FFT(a,-1); } void cdq(int l,int r) { if(l==r) { res[l]=(res[l]+a[l])%P; return ; } int mid=(l+r)>>1; cdq(l,mid); //fft int len=1; while(len<mid-2*l+r-1)len<<=1; for(int i=0; i<len; i++)va[i].i=va[i].r=vb[i].i=vb[i].r=0; for(int i=0; i+l<=mid; i++) { va[i].r=res[i+l]; va[i].i=0; } for(int i=0; i+1<=r-l; i++) { vb[i].r=a[i+1]; vb[i].i=0; } Conv(va,vb,len); for(int i=mid+1; i<=r; i++) res[i]=(res[i]+(int)(va[i-1-l].r+0.5))%P; cdq(mid+1,r); } int main() { FIN; while(cin>>n&&n) { for(int i=1; i<=n; i++)res[i]=0; for(int i=1; i<=n; i++) { scanf("%d",&a[i]); a[i]%=P; } cdq(1,n); cout<<res[n]<<endl; } return 0; }