TopicsSource
http://acm.hdu.edu.cn/showproblem.php?pid=5730
Description
Perhaps the sea ' s definition of a shell is the pearl. However, in my view, a shell necklace with n beautiful shells contains the most sincere feeling for my best lover Arrietty , but even that's not enough.
Suppose the shell necklace is a sequence of shells (not a chain end to end). Considering I continuous shells in the shell necklace, I know that there exist different schemes to decorate the I shells Together with one declaration of love.
I want to decorate all the shells with some declarations of love and decorate each shell just one time. As a problem, I want to know the total number of schemes.
Input
There is multiple test cases (no more than-cases and no more than 1 in extreme case), ended by 0.
For each test cases, the first line contains a integer n, meaning the number of shells in this shell necklace, where 1≤n≤ Following line was a sequence with n non-negative integer a1,a2,..., an, and ai≤107 meaning the number of schemes to Deco Rate I continuous shells together and a declaration of love.
Output
For each test case, print one line containing the total number of Schemes module 313 (three hundred and thirteen implies th E March 13th, a special and purposeful day).
Sample Input
3
1 3 7
4
2 2 2 2
0
Sample Output
14
54
Analysis
The topic probably says that the number of consecutive I (1<=i<=n) shells combined into a necklace of a[i], the total number of packages to combine into a necklace containing n shells.
- Dp[i] Represents the total number of packages combined into a necklace containing I shells
- Transfer: Dp[i]=σdp[i-j]*a[j] (1<=j<=i)
The time Complexity O (N2) is not possible if the direct enumeration is transferred.
In fact, this transfer equation is a relatively special convolution form, you can use FFT to seek, but from 1 to N in turn, the time complexity is O (N2LOGN).
And the use of CQD division, the process of each treatment accumulated in the left half of the interval has been obtained DP value of the state to the right half of each State contribution, this contribution is that the equation with an FFT, so the time complexity by the main theorem is known as O (nlog2n).
This is a very classic topic, although now do.
Code
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm>using namespace std;# Define INF (1<<30) #define MAXN 333333const Double Pi=acos (-1.0); struct complex{double real,imag; Complex (Double _real,double _imag): Real (_real), Imag (_imag) {}complex () {}complex operator+ (const Complex &CP) Const{return Complex (REAL+CP.REAL,IMAG+CP.IMAG);} Complex operator-(const Complex &CP) Const{return Complex (REAL-CP.REAL,IMAG-CP.IMAG);} Complex operator* (const Complex &CP) Const{return Complex (REAL*CP.REAL-IMAG*CP.IMAG,REAL*CP.IMAG+CP.REAL*IMAG);} void SetValue (double _real=0,double _imag=0) {real=_real; imag=_imag;}}; int Len; Complex WN[MAXN],WN_ANTI[MAXN]; void FFT (Complex y[],int op) {for (int i=1,j=len>>1,k; i<len-1; ++i) {if (i<j) swap (y[i],y[j]); k=len>>1 ; while (j>=k) {j-=k;k>>=1;} if (j<k) j+=k;} for (int h=2; h<=len; h<<=1) {Complex wn= (Op==1?wn[h]:wn_anti[h]), for (int i=0; i<len; i+=h) {Complex W (1,0); for (int j=i; j<i+ (H>>1); ++J) {Complex u=y[j],t=w*y[j+ (h>>1)];y[j]=u+t;y[j+ (h>>1)]=u-t; W=w*wn;}}} if (op==-1) {for (int i=0; i<len; ++i) Y[i].real/=len;}} void convolution (Complex a[],complex b[],int N) {for (len=1; len< (n<<1); len<<=1); for (int i=n; i<len; + +i) {a[i].setvalue (); B[i].setvalue ();} FFT (a,1); FFT (b,1); for (int i=0; i<len; ++i) {a[i]=a[i]*b[i];} FFT (a,-1);} int a[111111],d[111111]; Complex a[maxn],b[maxn];void CDQ (int l,int r) {if (l==r) {d[l]+=a[l];d [L]%=313;return;} int MID=L+R>>1;CDQ (L,MID), for (int i=l; i<=mid; ++i) A[i-l].setvalue (D[i]), for (int i=0; i<=r-l; ++i) B[i]. SetValue (A[i]); for (int i=mid-l+1; i<=r-l; ++i) A[i].setvalue (); Convolution (a,b,r-l+1), for (int i=mid+1; i<=r; ++i) {d[i]+= (Long Long) (a[i-l].real+0.5))%313;d[i]%=313;} CDQ (mid+1,r);} int main () {for (int i=0; i<maxn; ++i) {wn[i].setvalue (cos (2.0*pi/i), sin (2.0*pi/i)); Wn_anti[i].setvalue (wn[i].real ,-wn[i].imag);} int N;while (~SCANF ("%d", &n) && N) {for (int i=1; i<=n; ++i) {scanf("%d", a+i); a[i]%=313;} Memset (d,0,sizeof (d)), CDQ (1,n);p rintf ("%d\n", D[n]);} return 0;}
HDU5730 Shell Necklace (DP + CDQ + FFT)