Topic links
\ (description\)
There are \ ( n\) lengths ( 1,2,\ldots,n\) of beads, each with a \ (a_i\) species, each number of unlimited. How many methods are used to compose a string of length \ (n\) . Answer to \ (313\) modulo.
\ (solution\)
Make\ (f_i\)Represents a composition length of\ (i\)The number of scenarios for the string, you can get the recursive type:\[f_i=\sum_{j=0}^{i-1}a_{i-j}f_j,\ f_0=1\]Or\ (f_i=\sum_{j=1}^{i-1}a_{i-j}f_j+a_i\)。
Such violence is\ (O (n^2) \)Of
Because the form of the operation is convolution, it can be used\ (fft\)Instead, this complexity is\ (O (n^2\log n) \)。 Then apply CDQ to divide and conquer.\ (O (n\log^2 n) \)The
In the process of division, the first calculation\ (j\in [l,mid]\)Of\ (f_j\)And\ (a\)Do convolution, you can get the interval\ ([l,mid]\)Right\ (f_i,\ i\in[mid+1,r]\)'s contribution. That\[f_{i,i\in[mid+1,r]}+=\sum_{j=l}^{mid}a_{i-j}f_j\]
\ (A_{1\sim r-l}\)And\ (F_{l\sim mid}\)The first of the polynomial obtained after convolution\ (mid-l+i\)Item, which is the\ (f_{mid+i}\)'s contribution.
This item is from\ (0\)Numbered, if the\ (a_0=0\)This item is a convolution, the original first\ (mid-l+i\)The subscript of the item is\ (mid-l+i\)(Nothing to use it, but the internet is so written, understand why the day to add\ (a_0\), after writing the code to understand. )
Don't understand the convolution well enough.
Look at the online puzzle is not much to say clearly, the code runs slowly →_→
686MS 11196k#include <cmath> #include <cstdio> #include <cctype> #include <cstring> #include <algorithm> #define GC () GetChar () #define MOD (313) const double Pi=acos ( -1); const int n=1e5+5,m= (1<<18) +1;/ /262144int n,a[n],rev[m],f[n];struct complex{double x, y; Complex () {} Complex (double x,double y): x (x), Y (y) {} Complex operator + (const Complex &a) {return Complex (x+a.x, Y+A.Y);} Complex operator-(const Complex &a) {return Complex (x-a.x, Y-A.Y);} Complex operator * (const Complex &a) {return Complex (X*A.X-Y*A.Y, x*a.y+y*a.x);}} A[m],b[m];inline int read () {int now=0;register char c=gc (); for (;! IsDigit (c); C=GC ()); for (; IsDigit (c); now=now*10+c-' 0 ', C=GC ()); return now;} void FFT (Complex *a,int lim,int opt) {for (int i=1; i<lim; ++i) if (I<rev[i]) Std::swap (A[i],a[rev[i]]); for (int i=2; i<=lim; i<<=1) {int mid=i>>1; Complex Wn (cos (pi/mid), Opt*sin (Pi/mid)), t;//wn (cos (2.0*pi/i), opT*sin (2.0*pi/i)), T; for (int j=0; j<lim; j+=i) {Complex W (1,0); for (int k=0; k<mid; ++k,w=w*wn) a[j+mid+k]=a[j+k]-(t=a[j+mid+k]*w), a[j+k]=a[j+k]+t; }} if (Opt==-1) for (int i=0; i<lim; ++i) A[i].x/=lim;} void Calc (int *a,int len1,int *b,int len2) {int lim=1, l=-1; while (LIM<=LEN1+LEN2) lim<<=1, ++l; for (int i=1; i<lim; ++i) rev[i]= (rev[i>>1]>>1) | ((i&1) <<l); for (int i=0; i<len1; ++i) A[i]=complex (a[i],0); for (int i=len1; i<lim; ++i) A[i]=complex (0,0); for (int i=0; i<len2; ++i) B[i]=complex (b[i],0); for (int i=len2; i<lim; ++i) B[i]=complex (0,0); FFT (a,lim,1), FFT (b,lim,1); for (int i=0; i<lim; ++i) a[i]=a[i]*b[i]; FFT (a,lim,-1);} void CDQ (int l,int r) {if (l==r) return; int mid=l+r>>1; CDQ (L,mid); Calc (a+1,r-l,f+l,mid-l+1); for (int i=mid+1; i<=r; ++i) (f[i]+= (Long Long) (a[i-l-1].x+0.5)%mod)%=mod;//mid+1-l, mid+1//Calc (a,r-l+1,f+l,mid-l+1);//a_0=0 this one a[] subscript will not use-1. for (int i=mid+1; i<=r; ++i) (f[i]+= ((Long) (a[i-l].x+0.5)%mod))%=mod;//mid+1-l-mid+1//for (int i=mid-l+1 ; i<=r-l; ++i) (f[l+i]+= (Long Long) (a[i].x+0.5)%mod)%=mod;//longlong!//mid+i <= R-I <= Mid-l+r-mid = r-l? CDQ (mid+1,r);} int main () {while (N=read ()) {memset (f,0,sizeof f); for (int i=1; i<=n; ++i) A[i]=read ()%mod; F[0]=1, CDQ (0,n), printf ("%d\n", F[n]); } return 0;}
Hdu.5730.shell Necklace (divide-and-conquer FFT)