题意:dp[n] = ∑ ( dp[n-i]*a[i] )+a[n], ( 1 <= i < n)
cdq分治。
计算出dp[l ~ mid]后,dp[l ~ mid]与a[1 ~ r-l]做卷积运算。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 4e5+5; 4 const int mod = 313; 5 const double pi = acos(-1.0); 6 struct comp{ 7 double r,i;comp(double _r=0,double _i=0){r=_r;i=_i;} 8 comp operator+(const comp x){return comp(r+x.r,i+x.i);} 9 comp operator-(const comp x){return comp(r-x.r,i-x.i);} 10 comp operator*(const comp x){return comp(r*x.r-i*x.i,r*x.i+i*x.r);} 11 }x[N], y[N]; 12 void FFT(comp a[],int n,int t){ 13 for(int i=1,j=0;i<n-1;i++){ 14 for(int s=n;j^=s>>=1,~j&s;); 15 if(i<j)swap(a[i],a[j]); 16 } 17 for(int d=0;(1<<d)<n;d++){ 18 int m=1<<d,m2=m<<1; 19 double o=pi/m*t;comp _w(cos(o),sin(o)); 20 for(int i=0;i<n;i+=m2){ 21 comp w(1,0); 22 for(int j=0;j<m;j++){ 23 comp &A=a[i+j+m],&B=a[i+j],t=w*A; 24 A=B-t;B=B+t;w=w*_w; 25 } 26 } 27 } 28 if(t==-1)for(int i=0;i<n;i++)a[i].r/=n; 29 } 30 31 int a[N], dp[N], n; 32 void cdq(int l,int r){ 33 if(l == r){ 34 dp[l] = (dp[l]+a[l])%mod; 35 return; 36 } 37 int mid = l+r >> 1; 38 cdq(l, mid); 39 int len = 1; 40 while(len <= (r-l+1)) len <<= 1; 41 for(int i = 0; i < len; i++) 42 x[i] = y[i] = comp(0, 0); 43 for(int i = l; i <= mid; i++) 44 x[i-l] = comp(dp[i], 0); 45 for(int i = 1; l+i <= r; i++) 46 y[i-1] = comp(a[i], 0); 47 FFT(x, len, 1); FFT(y, len, 1); 48 for(int i = 0; i < len; i++) 49 x[i] = x[i]*y[i]; 50 FFT(x, len, -1); 51 52 for(int i = mid+1; i <= r; i++){ 53 dp[i] += x[i-l-1].r+0.5; 54 dp[i] %= mod; 55 } 56 cdq(mid+1,r); 57 } 58 59 int main(){ 60 while(scanf("%d", &n), n){ 61 for(int i = 1; i <= n; i++){ 62 scanf("%d", a+i); 63 a[i] %= mod; 64 dp[i] = 0; 65 } 66 cdq(1, n); 67 printf("%d\n", dp[n]); 68 } 69 return 0; 70 }