【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5730

【题目大意】

  给出一个数组w,表示不同长度的字段的权值,比如w[3]=5表示如果字段长度为3,则其权值为5,现在有长度为n的字段,求通过不同拆分得到的字段权值乘积和。

【题解】

  记DP[i]表示长度为i时候的答案,DP[i]=sum_{j=0}^{i-1}DP[j]w[i-j],发现是一个卷积的式子,因此运算过程可以用FFT优化,但是由于在计算过程中DP[j]是未知值,顺次计算复杂度是O(n2logn),考虑到加法运算对乘法运算可分配,因此可以采取CDQ分治,利用递归统计每个区间内左边DP值对右边DP值的贡献,对于每次贡献值的计算则利用FFT进行优化,优化时间复杂度至O(nlognlogn)。

【代码】

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=524300,P=313;
int n,pos[N];
namespace FFT{
struct comp{
double r,i;
comp(double _r=0,double _i=0):r(_r),i(_i){}
comp operator +(const comp&x){return comp(r+x.r,i+x.i);}
comp operator -(const comp&x){return comp(r-x.r,i-x.i);}
comp operator *(const comp&x){return comp(r*x.r-i*x.i,i*x.r+r*x.i);}
comp conj(){return comp(r,-i);}
}A[N],B[N];
const double pi=acos(-1.0);
void FFT(comp a[],int n,int t){
for(int i=1;i<n;i++)if(pos[i]>i)swap(a[i],a[pos[i]]);
for(int d=0;(1<<d)<n;d++){
int m=1<<d,m2=m<<1;
double o=pi*2/m2*t;
comp _w(cos(o),sin(o));
for(int i=0;i<n;i+=m2){
comp w(1,0);
for(int j=0;j<m;j++){
comp& A=a[i+j+m],&B=a[i+j],t=w*A;
A=B-t;
B=B+t;
w=w*_w;
}
}
}if(t==-1)for(int i=0;i<n;i++)a[i].r/=n;
}
void mul(int *a,int *b,int *c,int k){
int i,j;
for(i=0;i<k;i++)A[i]=comp(a[i],b[i]);
j=__builtin_ctz(k)-1;
for(int i=0;i<k;i++){pos[i]=pos[i>>1]>>1|((i&1)<<j);}
FFT(A,k,1);
for(int i=0;i<k;i++){
j=(k-i)&(k-1);
B[i]=(A[i]*A[i]-(A[j]*A[j]).conj())*comp(0,-0.25);
}FFT(B,k,-1);
for(int i=0;i<k;i++)c[i]=(long long)(B[i].r+0.5)%P;
}
}
int w[N],a[N],b[N],c[N],F[N];
void CDQ(int l,int r){
if(l==r){F[l]+=w[l];F[l]%=P;return;}
int mid=(l+r)>>1;
CDQ(l,mid); int N=1;
while(N<r-l)N<<=1;
for(int i=0;i<=mid-l;i++)a[i]=F[i+l];
for(int i=mid-l+1;i<N;i++)a[i]=0;
for(int i=0;i<r-l;i++)b[i]=w[i+1];
for(int i=r-l;i<N;i++)b[i]=0;
FFT::mul(a,b,c,N);
for(int i=mid+1;i<=r;i++){
F[i]+=c[i-l-1];
F[i]%=P;
}CDQ(mid+1,r);
}
int main(){
while(~scanf("%d",&n)&&n){
F[0]=1;
for(int i=1;i<=n;i++){
scanf("%d",&w[i]);
w[i]%=P;
F[i]=0;
}CDQ(1,n);
printf("%d\n",F[n]);
}return 0;
}

  

HDU 5730 Shell Necklace(CDQ分治+FFT)的更多相关文章

  1. HDU 5730 Shell Necklace cdq分治+FFT

    题意:一段长为 i 的项链有 a[i] 种装饰方式,问长度为n的相连共有多少种装饰方式 分析:采用dp做法,dp[i]=∑dp[j]*a[i-j]+a[i],(1<=j<=i-1) 然后对 ...

  2. HDU Shell Necklace CDQ分治+FFT

    Shell Necklace Problem Description Perhaps the sea‘s definition of a shell is the pearl. However, in ...

  3. hdu 5730 Shell Necklace [分治fft | 多项式求逆]

    hdu 5730 Shell Necklace 题意:求递推式\(f_n = \sum_{i=1}^n a_i f_{n-i}\),模313 多么优秀的模板题 可以用分治fft,也可以多项式求逆 分治 ...

  4. hdu 5730 Shell Necklace fft+cdq分治

    题目链接 dp[n] = sigma(a[i]*dp[n-i]), 给出a1.....an, 求dp[n]. n为1e5. 这个式子的形式显然是一个卷积, 所以可以用fft来优化一下, 但是这样也是会 ...

  5. HDU.5730.Shell Necklace(分治FFT)

    题目链接 \(Description\) 有\(n\)个长度分别为\(1,2,\ldots,n\)的珠子串,每个有\(a_i\)种,每种个数不限.求有多少种方法组成长度为\(n\)的串.答案对\(31 ...

  6. hdu 5730 Shell Necklace——多项式求逆+拆系数FFT

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5730 可以用分治FFT.但自己只写了多项式求逆. 和COGS2259几乎很像.设A(x),指数是长度,系数 ...

  7. hdu5730 Shell Necklace 【分治fft】

    题目 简述: 有一段长度为n的贝壳,将其划分为若干段,给出划分为每种长度的方案数,问有多少种划分方案 题解 设\(f[i]\)表示长度为\(i\)时的方案数 不难得dp方程: \[f[i] = \su ...

  8. #8 //HDU 5730 Shell Necklace(CDQ分治+FFT)

    Description 给出长度分别为1~n的珠子,长度为i的珠子有a[i]种,每种珠子有无限个,问用这些珠子串成长度为n的链有多少种方案 题解: dp[i]表示组合成包含i个贝壳的项链的总方案数 转 ...

  9. hdu 5730 Shell Necklace —— 分治FFT

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5730 DP式:\( f[i] = \sum\limits_{j=1}^{i} f[i-j] * a[j] ...

随机推荐

  1. javascript限制input只允许输入数字

    在做数据提交的表单时,经常要对input输入内容的类型进行限制,譬如javascript限制input只允许输入数字,最好的方法当然是使用javascript,因为它不用与服务器交互,大大减轻了服务器 ...

  2. js-计算器

    <div class="main"><h1>HTML5-计算器</h1>            <input id="num1& ...

  3. loading 动画效果(收藏起来以后留着慢慢用)

    动画效果一: html代码: <div class="spinner">   <div class="rect1"></div&g ...

  4. IIS怎么设置本地域名解析(本地域名测试配置)

    对于IIS相信大家都不陌生,可以用来作为网站服务器,可以解析网站内容,访问时可以用端口的方式访问,也可以用域名的方式访问.下面我就介绍一下,怎么在本地用域名的方式访问,怎么用IIS进行本地域名解析. ...

  5. Flink资料(8) -- Flink代码贡献的指导及准则

    本文翻译自Contributing Code ----------------------------------------- Apache Flink是由自愿的代码贡献者维护.优化及扩展的.Apa ...

  6. Entity Framework 数据部分更新之Attach &&Detach

    我们经常会遇到这样的问题:Update一个entity的部分数据时,通常需要new一个新的对象,然后事这新的对象Attach到Context中,代码如下所示: /// <summary> ...

  7. ELMAH+MVC4+SQLite 错误日志

    任何程序我想无论是在调试开发阶段还是上线运营阶段,都能够使人“放心”,不要出什么意外,也不要玩什么心跳:那就需要比较到位和及时的异常与错误日志模块. 本文将简要描述ELMAH.MVC4与SQLite这 ...

  8. POJ1185 炮兵阵地 状态压缩

    因为不知道不同的博客怎么转,就把别人的复制过来了,这个题解写的非常好,原地址为: http://hi.baidu.com/wangxustf/item/9138f80ce2292b8903ce1bc7 ...

  9. Java中的图形界面编程

    前言 正文 Java中的图形界面编程 AWT/Swing AWT(Abstract Window ToolKits,抽象窗体工具集) 1.容器类:用来存储组件,实现容器布局 2.组件类:实现界面的一些 ...

  10. xcode xib 加载 、注意点

    加载xib2中方式 NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"xib名称" owner:nil options: ...