HDU 5730 Shell Necklace(dp+cdq分治+FFT优化)
2016-10-08 11:30
375 查看
一串项链是n个珠子组成,如果i个珠子连续,可以被认为是模式i,贡献是ai
对于一串珠子,如果用了模式b1,b2,...bk,贡献就是∏mi=1abi
求n长度的项链,所有情况的贡献和
可以列出dp方程,f[i]表示长度为i的项链,所有情况的贡献和
f[i]=∑ij=1f[i−j]×aj
O(n)的状态,O(n)的转移,总复杂度O(n2),GG
观察这个式子很像卷积的形式,于是可以用cdq分治+FFT来优化一波
先求出前面的f的值,然后去算后面的f的值,分治logn复杂度
然后每次分治的时候,需要nlogn的FFT计算
总复杂度O(nlog2n)
代码:
对于一串珠子,如果用了模式b1,b2,...bk,贡献就是∏mi=1abi
求n长度的项链,所有情况的贡献和
可以列出dp方程,f[i]表示长度为i的项链,所有情况的贡献和
f[i]=∑ij=1f[i−j]×aj
O(n)的状态,O(n)的转移,总复杂度O(n2),GG
观察这个式子很像卷积的形式,于是可以用cdq分治+FFT来优化一波
先求出前面的f的值,然后去算后面的f的值,分治logn复杂度
然后每次分治的时候,需要nlogn的FFT计算
总复杂度O(nlog2n)
代码:
#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <sstream> #include <cstdlib> #include <iostream> #include <algorithm> #pragma comment(linker,"/STACK:102400000,102400000") using namespace std; #define MAX 100005 #define MAXN 1000005 #define maxnode 105 #define sigma_size 30 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lrt rt<<1 #define rrt rt<<1|1 #define middle int m=(r+l)>>1 #define LL long long #define ull unsigned long long #define mem(x,v) memset(x,v,sizeof(x)) #define lowbit(x) (x&-x) #define pii pair<int,int> #define bits(a) __builtin_popcount(a) #define mk make_pair #define limit 10000 //const int prime = 999983; const int INF = 0x3f3f3f3f; const LL INFF = 0x3f3f; const double pi = acos(-1.0); const double inf = 1e18; const double eps = 1e-6; const LL mod = 313; const ull mx = 133333331; /*****************************************************/ inline void RI(int &x) { char c; while((c=getchar())<'0' || c>'9'); x=c-'0'; while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; } /*****************************************************/ const double PI = acos(-1.0); struct Complex { double real, image; Complex(double _real, double _image) { real = _real; image = _image; } Complex(){} }; Complex operator + (const Complex &c1, const Complex &c2) { return Complex(c1.real + c2.real, c1.image + c2.image); } Complex operator - (const Complex &c1, const Complex &c2) { return Complex(c1.real - c2.real, c1.image - c2.image); } Complex operator * (const Complex &c1, const Complex &c2) { return Complex(c1.real*c2.real - c1.image*c2.image, c1.real*c2.image + c1.image*c2.real); } int rev(int id, int len) { int ret = 0; for(int i = 0; (1 << i) < len; i++) { ret <<= 1; if(id & (1 << i)) ret |= 1; } return ret; } Complex A[280000]; /////////大小要修改,不要忘记 void FFT(Complex* a, int len, int DFT){//对a进行DFT或者逆DFT, 结果存在a当中 //Complex* A = new Complex[len]; 这么写会爆栈 for(int i = 0; i < len; i++) A[rev(i, len)] = a[i]; for(int s = 1; (1 << s) <= len; s++) { int m = (1 << s); Complex wm = Complex(cos(DFT*2*PI/m), sin(DFT*2*PI/m)); for(int k = 0; k < len; k += m) { Complex w = Complex(1, 0); for(int j = 0; j < (m >> 1); j++) { Complex t = w*A[k + j + (m >> 1)]; Complex u = A[k + j]; A[k + j] = u + t; A[k + j + (m >> 1)] = u - t; w = w*wm; } } } if(DFT == -1) for(int i = 0; i < len; i++) A[i].real /= len, A[i].image /= len; for(int i = 0; i < len; i++) a[i] = A[i]; return; } Complex a[280000], b[280000];//对应的乘积的长度不会超过100000, 也就是不超过(1 << 17) = 131072 int f[MAX]; int x[MAX]; void cdq(int l,int r){ if(l==r) return; int mid=(l+r)/2; cdq(l,mid); int len=1; while(len<=r-l+1) len<<=1; for(int i=0;i<len;i++){ if(l+i<=mid) a[i]=Complex(f[l+i],0); else a[i]=Complex(0,0); if(l+i+1<=r) b[i]=Complex(x[i+1],0); else b[i]=Complex(0,0); } FFT(a,len,1); FFT(b,len,1); for(int i=0;i<len;i++) a[i]=a[i]*b[i]; FFT(a,len,-1); for(int i=mid+1;i<=r;i++){ f[i]+=floor(a[i-l-1].real+0.5); f[i]%=mod; } cdq(mid+1,r); } int main(){ //freopen("in.txt","r",stdin); int n; while(cin>>n&&n){ for(int i=1;i<=n;i++) scanf("%d",&x[i]),x[i]%=mod; mem(f,0); f[0]=1; cdq(0,n); printf("%d\n",f ); } return 0; }
相关文章推荐
- HDU 5730 Shell Necklace(CDQ分治+FFT)
- hdu 5730 Shell Necklace(2016多校第一场)FFT+分治
- hdu 5730 Shell Necklace
- [HDU 5730] Shell Necklace (FFT+CDQ分治)
- hdu 5730 Shell Necklace [分治fft | 多项式求逆]
- hdu 5730 2016 Multi-University Training Contest 1 Shell Necklace 解题报告
- HDU 5730 Shell Necklace(FFT+分治)
- HDU 5730: Shell Necklace 分治FFT
- HDU 5730 多校1 Shell Necklace (CDQ分治+FFT)
- 【HDU 5730】Shell Necklace
- Hdu 5730 Shell Necklace(cdq+fft)
- HDU 5730 Shell Necklace(CDQ分治+FFT)
- HDU 5730 Shell Necklace cdq分治+FFT
- HDU - 5730 Shell Necklace CDQ分治+fft
- HDU 3874 Necklace 树状数组的应用
- HDU-3874 Necklace 树状数组+离线处理
- 【HDU】3474 Necklace
- hdu 3333 Turing Tree & hdu 3874 Necklace (成段更新)
- hdu 2660 Accepted Necklace
- HDU 3474 Necklace