Description
gives beads with lengths of 1~n, and beads of length I have a[i], each with an infinite number of beads, asking how many options are used to string the beads into a chain of length n
input< /strong>
Multiple sets of use cases, each set of use cases first enters an integer n for the chain length, followed by n integer ai to represent the number of beads of length I, to n=0 end input (n<=10^5,0<=ai<=10^7)
Output
For each set of use cases, outputs the number of scenarios, results modulo 313
Sample Input
3
1 3 7
4
2 2 2 2
0 Sample Output
+
[
solution
] Dp[i] represents the number of schemes that are strung with these beads into a chain of length I and makes dp[0]= 1, easy to get the transfer equation
by the violence of the dp[n] time complexity O (n^2), obviously not, considering the upper right is a convolution form, so with CDQ division +fft to reduce complexity, assuming CDQ (l,r) to find dp[l],dp[l+1],..., DP[R] Value, then if you have CDQ (L,mid) to find out dp[l],dp[l+1],..., Dp[mid], consider dp[l],dp[l+1],..., Dp[mid] to dp[mid+1],dp[mid+2],..., Dp[r] G[i] dp[l],..., Dp[mid] contribution to dp[i], so x[i]=dp[i+l] (i=0,..., mid-l), y[i]=a[i+1] (i=0,..., r-l-1),
So the x sequence and the y sequence do the FFT to get the z sequence, and then get the G sequence
Total time complexity O (nlognlogn)
Code
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std;
typedef long Long LL;
#define MOD 313 #define MAXN 100005 #define MAXFFT 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[MAXFFT];
int POS[MAXFFT];
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[maxfft],y[maxfft],z[maxfft];
void FFT (int *a,int *b,int n,int m,int *c) {int len=1;
while (len< (n+m) >>1) len<<=1;
Fft_init (len);
for (int i=n/2;i<len;i++) x[i].a=x[i].b=0;
for (int i=m/2;i<len;i++) y[i].a=y[i].b=0;
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];
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]= (LL) (z[i>>1].b+0.5)%mod;
else c[i]= (LL) (z[i>>1].a+0.5)%mod;
} int n,a[maxn],b[maxn<<1],dp[maxn];
void Deal (int l,int R) {if (l==r) {dp[l]+=a[l],dp[l]%=mod;
return;
} int mid= (L+R) >>1;
Deal (L,MID);
FFT (DP+L,A+1,MID-L+1,R-L+2,B);
for (int i=mid+1;i<=r;i++) Dp[i]+=b[i-l-1],dp[i]%=mod;
Deal (MID+1,R);
} int main () {while (scanf ("%d", &n), N) {memset (dp,0,sizeof (DP));
for (int i=1;i<=n;i++) scanf ("%d", &a[i]), a[i]%=mod;
Deal (1,n);
printf ("%d\n", Dp[n]);
} return 0; }