hdu5730 Shell Necklace "Divide and conquer FFT"

Source: Internet
Author: User

Tag: while void \ n Const floor How long def length

Topic

Briefly:

There is a shell of length n, divides it into several segments, gives the number of schemes divided into each length, and asks how many kinds of partitioning schemes

Exercises

Set \ (f[i]\) indicates the number of scenarios when the length is \ (i\)
The DP equation is not rare:
\[f[i] = \sum\limits_{j=0}^{i} a[j] * f[i-j]\]

Consider transfer
The direct transfer is \ (O (n^2) \)
How to optimize?
It is easy to find that the transfer equation is very special and is a convolution form
Consider FFT

Divide and conquer FFT

Divide-and-conquer FFT solves the problem of fast computation of such a transfer equation.
\[f[i] = \sum\limits_{j=0}^{i} a[j] * f[i-j]\]

Consider the model of CDQ Division:
We first deal with the left half interval, and then we use the \ (f[i]\) of the left half interval to update the answer of the right half interval.
Specifically, the contribution of the left half to the right one position \ (r\) is:
\[\SUM\LIMITS_{I=L}^{MID} f[i] * a[r-i]\]
is also a convolution form, the first \ (r\) item of the polynomial product
So we can use \ (f[i]\) and \ (a[i]\) constructs two polynomial, makes the FFT, then directly accumulates the corresponding position the value to the right half corresponding position \ (f[i]\) to go

We solved the problem.

#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#define LL Long Long int#define Redge (U) for (int k = h[u],to; k; k = ed[k].nxt)#define REP (i,n) for (int i = 1; I <= (n); i++)#define BUG (s,n) for (int i = 1; I <= (n); i++) cout<<s[i]<< '; puts ("");using namespaceStdConst intMAXN =400005, MAXM =100005, INF =1000000000, P =313;inline intRead () {intout =0, flag =1;Charc = GetChar (); while(C < -|| C > $){if(c = ='-') flag =-1; c = GetChar ();} while(c >= -&& C <= $) {out = (out <<3) + (out <<1) + C- -; c = GetChar ();}returnOut * FLAG;}Const DoublePI = ACOs (-1);structe{DoubleR,i; E () {} e (DoubleADoubleb): R (a), I (b) {} Eoperator=(Const int& B) {r = b; i =0;return* This; }};inlineEoperator+(Conste& A,Conste& b) {returnE (A.R + b.r,a.i + b.i);}inlineEoperator-(Conste& A,Conste& b) {returnE (A.R-B.R,A.I-B.I);}inlineEoperator*(Conste& A,Conste& b) {returnE (A.R * B.R-A.I * B.I,A.R * B.I + B.R * a.i);}inlineEoperator*= (e& A,Conste& b) {return(A = a * b);}inlineEoperator/(e& A,Const Double& B) {returnE (a.r/b,a.i/b);}inlineEoperator/= (e& A,Const Double& B) {return(A = A/b);}intN,M,L,R[MAXN];voidFFT (e* A,intf) { for(inti =0; I < n; i++)if(I < r[i]) swap (a[i],a[r[i]); for(inti =1; I < n; I <<=1) {E wn (cos (pi/i), f * sin (pi/i)); for(intj =0; J < N; J + = (i <<1)) {E W (1,0); for(intK =0; K < I;                K++,w *= wn) {E x = a[j + k],y = w * a[j + k + i]; A[j + K] = x + y;            A[j + k + i] = x-y; }        }    }if(f = =-1) for(inti =0; I < n; i++) a[i]/= N;} E A[MAXN],B[MAXN];intN,A[MAXN],F[MAXN];voidSolveintLintR) {if(L = = r) {F[l] = (F[l] + a[l])% P;return; }intMID = L + R >>1;    Solve (L,mid); n = mid-l +1; for(inti =0; I < n;    i++) A[i] = f[l + i]; m = r-l +1; for(inti =0; I < m; i++) B[i] = A[i +1]; m = n + M; L =0; for(n =1; n <= m; N <<=1) l++; for(inti =0; I < n; i++) R[i] = (r[i >>1] >>1) | ((I &1) << (L-1)); FFT (A,1); FFT (B,1); for(inti =0; I < n;    i++) A[i] *= b[i]; FFT (A,-1); for(inti = mid +1; I <= R; i++) {F[i] = (F[i] + (int) Floor (A[i-l-1].R +0.5)% p)% p; } for(inti =0; I < n; i++) A[i] = b[i] =0; Solve (mid +1, r);}intMain () { while((~SCANF ("%d", &n)) && N) { for(inti =1; I <= N;            i++) {A[i] = read ()% P; F[i] =0; } Solve (1, N); printf"%d\n", F[n]); }return 0;}

hdu5730 Shell Necklace "Divide and conquer FFT"

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.