【HDU5730】Shell Necklace——CDQ+FFT

来源:互联网 发布:伊朗空军实力知乎 编辑:程序博客网 时间:2024/05/21 08:50
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem 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 is 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 are multiple test cases(no more than 20 cases and no more than 1 in extreme case), ended by 0.

For each test cases, the first line contains an integer n, meaning the number of shells in this shell necklace, where 1≤n≤105. Following line is a sequence with n non-negative integer a1,a2,…,an, and ai≤107 meaning the number of schemes to decorate i continuous shells together with 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 the march 13th, a special and purposeful day).

Sample Input

3
1 3 7
4
2 2 2 2
0

Sample Output

14
54

Hint

For the first test case in Sample Input, the Figure 1 provides all schemes about it. The total number of schemes is 1 + 3 + 3 + 7 = 14.

Author

HIT

题意:给你长度为i的项链的组合的情况是a[i],求组成长度为n的项链的方案数。
思路:比较容易想到的就是dp[i]=j=0idp[j]×a[ij],但是n=100000,所以n2的时间复杂度肯定是不行的。对于这种dp前面的结果对后面的结果有贡献的我们可以利用CDQ分治进行解决。对于一个区间我们先处理出前一半的区间的结果,然后计算前一半区间结果对后一半区间的贡献。
假设区间[L,R]mid=L+R2,我们现在已经算出[L,mid],s1=(midL+1),s2=(RL+1),我们构造两个多项式

f1=dp[L]x0+dp[L+1]x1+dp[mid]xs11f2=a[0]x0+a[1]x1+a[2]x2a[s2]xs2
,那么两个多项式相乘的结果为axy表示对长度为y+L的项链的贡献为a,想想为什么???
这样的话,我们就可以通过CDQ分治的方式降低时间复杂度O(n)log(n)log(n)

#include <bits/stdc++.h>#define CLR(a,b) memset(a,b,sizeof(a))using namespace std;const double Pi = acos(-1.0);const int maxn = 2e5+100;const int Mod = 313;struct Complex{    double real, imag;    Complex(){}    Complex(double _r,double _i):real(_r),imag(_i){}    Complex operator + (const Complex &a) const {        return Complex(real+a.real,imag + a.imag);    }    Complex operator - (const Complex &a) const {        return Complex(real-a.real,imag - a.imag);    }    Complex operator * (const Complex &a) const {        return Complex(real*a.real-imag*a.imag,real*a.imag+imag*a.real);    }    void Setvalue(double r,double i) {        real = r; imag = i;    }    void Output() {        printf("%f %f\n",real,imag);    }}a[maxn*4],b[maxn*4];int dp[maxn],num[maxn];int n,len;void Rader(Complex y[]) {    for(int i = 1,j = len>>1;i<len-1;i++) {        if(i<j) swap(y[i],y[j]);        int k = len>>1;        while(j>=k) {            j-=k;            k>>=1;        }        if(j<k) j+=k;    }}void FFT(Complex y[],int op) {    Rader(y);    for(int h = 2;h<=len;h<<=1) {        Complex wn(cos(2*Pi*op/h),sin(2*Pi*op/h));        for(int i = 0;i<len;i+=h) {            Complex w(1,0);            for(int j = i;j<i+h/2;j++) {                Complex u = y[j];                Complex v = w*y[j+h/2];                y[j] = u+v;                y[j+h/2] = u-v;                w =w*wn;            }        }    }    if(op == -1) {        for(int i = 0;i<len;i++) y[i].real /= len;    }}void CDQ(int L,int R) {//CDQ分治    if(L == R){         return ;    }    int mid = (L+R)>>1;    CDQ(L,mid);    len = 1;    while(len<=(R-L+1)) len<<=1;    for(int i =0;i<len;i++)  a[i].Setvalue(0,0);    for(int i =0;i<len;i++)  b[i].Setvalue(0,0);    for(int i = L;i <= mid; i++)  a[i-L].real+=dp[i];    for(int i = 0;i <R-L+1; i++)  b[i].real += num[i];    FFT(a,1);FFT(b,1);    for(int i = 0;i<len;i++) a[i] = a[i]*b[i];    FFT(a,-1);    for(int i = mid+1;i<=R;i++) {        dp[i]+=(int)(a[i-L].real+0.5);        dp[i]%=Mod;    }    CDQ(mid+1,R);}int main() {    while(~scanf("%d",&n) && n) {        CLR(dp,0);CLR(num,0);        for(int i = 1;i<=n;i++) {            scanf("%d",&num[i]);            num[i]%=Mod;        }        dp[0] = 1;        CDQ(0,n);        printf("%d\n",dp[n]);    }    return 0;}
1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝上不给退货怎么办 网购衣服买小了怎么办 淘宝上全球购买到假货怎么办 京东全球购税费怎么办 代购被海关税了怎么办 网上买猫被骗了怎么办 苏宁账号被冻结怎么办 九州娱乐提款未到账怎么办 法院拍卖后不足的余款怎么办 购车后余款没拿怎么办? 抵押房屋被执行后余款怎么办 苏宁无敌券过期怎么办 被亚马逊自营跟卖怎么办 苏宁易购绑定手机后解绑不了怎么办 手机qq注册号码忘了怎么办 原创头条号被限制推荐了怎么办 为什么打开app有广告怎么办 苹果手机浏览器总是弹出广告怎么办 手机上打开页面出现广告怎么办 电脑下面的任务栏变宽了怎么办 酷派手机总是出现广告怎么办 电脑弹出的热点新闻关闭不了怎么办 京东老是弹广告怎么办 电脑右下角出现无法显示网页怎么办 电脑右下角广告关不了怎么办 qq邮箱被冻结了怎么办 手机qq群自动发广告怎么办 济宁学院考研和上课冲突怎么办 考研但是大四上课多怎么办 试管促排卵泡少怎么办 京东退货卖家拒收怎么办 京东退货被卖家拒收怎么办 期货平台跑路了怎么办 浮云牧场没房了怎么办 融资股票停牌了怎么办 买入的股票停牌怎么办 淘宝抢到便宜货老板不发货怎么办 微信代购买到假货了怎么办 微信代购收到假货怎么办 苹果商店下载很慢怎么办 谷歌商店下载东西慢怎么办