1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| #include <bits/stdc++.h> using namespace std; const double PI=acos(-1.0); const int MO=313; const int N=100010; struct Complex { double x,y; Complex(double _x = 0.0,double _y = 0.0) { x = _x; y = _y; } Complex operator -(const Complex &b)const { return Complex(x-b.x,y-b.y); } Complex operator +(const Complex &b)const { return Complex(x+b.x,y+b.y); } Complex operator *(const Complex &b)const { return Complex(x*b.x-y*b.y,x*b.y+y*b.x); } } x[280000],y[280000]; int a[N],dp[N];
void change(Complex y[],int len) { int i,j,k; for(i = 1, j = len/2; i <len-1; i++) { if(i < j)swap(y[i],y[j]); k = len/2; while(j >= k) { j -= k; k /= 2; } if(j < k)j += k; } } void fft(Complex y[],int len,int on) { change(y,len); for(int h = 2; h <= len; h <<= 1) { Complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h)); for(int j = 0; j < len; j+=h) { Complex w(1,0); for(int k = j; k < j+h/2; k++) { Complex u = y[k]; Complex t = w*y[k+h/2]; y[k] = u+t; y[k+h/2] = u-t; w = w*wn; } } } if(on == -1) { for(int i = 0; i < len; i++) y[i].x /= len; } }
void cdq(int l,int r) { if (l==r) { dp[l]+=a[l]; dp[l]%=MO; return; } int mid=(l+r)>>1; cdq(l,mid); int len1=mid-l+1; int len2=r-l+1; int len=1; while (len<=len2) len<<=1; for (int i=0;i<len1;i++) { x[i]=Complex(dp[l+i],0); } for (int i=len1;i<len;i++) { x[i]=Complex(0,0); } for (int i=0;i<len2;i++) { y[i]=Complex(a[i],0); } for (int i=len2;i<len;i++) { y[i]=Complex(0,0); } fft(x,len,1); fft(y,len,1); for (int i=0;i<len;i++) { x[i]=x[i]*y[i]; } fft(x,len,-1); for (int i=mid+1;i<=r;i++) { dp[i]+=round(x[i-l].x); dp[i]%=MO; } cdq(mid+1,r); }
int main() { int n; while (scanf("%d",&n),n) { for (int i=1;i<=n;i++) { scanf("%d",&a[i]); a[i]%=MO; } memset(dp,0,sizeof(dp)); dp[0]=1; cdq(1,n); printf("%d\n",dp[n]); } return 0; }
|