HDU5730 Shell Necklace

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 999    Accepted Submission(s): 434

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 nnon-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

Source

2016 Multi-University Training Contest 1

Recommend

wange2014

一段长为x的项链作为一个整体,有a[x]种装饰方案。可以把不同的整体连接起来。问长为n的项链共有多少种方案。

动态规划 分治FFT

设f[i]为长为i的方案数,很明显 $ f[i]=\sum_{j=1}^{i} a[j]*f[i-j] $

模数是313,这数的原根是啥啊?不知道。模数这么小,用FFT就可以了。

PS1 注意读入a[]的时候就要顺手取模,不然很容易乘爆炸

PS2 我也不知道为什么我要多输出一个换行符,白WA了三次才看到

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #define LL long long
 7 using namespace std;
 8 const double pi=acos(-1.0);
 9 const int mod=313;
10 const int mxn=200010;
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
14     while(ch>=‘0‘ && ch<=‘9‘){x=x*10-‘0‘+ch;ch=getchar();}
15     return x*f;
16 }
17 struct com{
18     double x,y;
19     com operator + (const com &b){return (com){x+b.x,y+b.y};}
20     com operator - (const com &b){return (com){x-b.x,y-b.y};}
21     com operator * (const com &b){return (com){x*b.x-y*b.y,x*b.y+y*b.x};}
22     com operator / (const double v){return (com){x/v,y/v};}
23 }a[mxn<<2],b[mxn<<2];
24 int N,len,rev[mxn<<2];
25 void FFT(com *a,int flag){
26     for(int i=0;i<N;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
27     for(int i=1;i<N;i<<=1){
28         com wn=(com){cos(pi/i),flag*sin(pi/i)};
29         int p=i<<1;
30         for(int j=0;j<N;j+=p){
31             com w=(com){1,0};
32             for(int k=0;k<i;k++,w=w*wn){
33                 com x=a[j+k],y=w*a[j+k+i];
34                 a[j+k]=x+y;
35                 a[j+k+i]=x-y;
36             }
37         }
38     }
39     if(flag==-1)
40         for(int i=0;i<N;i++)a[i].x/=N;
41     return;
42 }
43 int n,w[mxn];
44 LL f[mxn];
45 void solve(int l,int r){
46     if(l==r){(f[l]+=w[l])%=mod;return;}
47     int mid=(l+r)>>1;
48     solve(l,mid);
49     int i,j,m=(r-l+1);
50     for(N=1,len=0;N<=m;N<<=1)++len;
51     for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
52     //
53     for(i=l;i<=mid;i++){a[i-l]=(com){f[i],0};}
54     for(i=mid-l+1;i<N;i++)a[i]=(com){0,0};
55     for(i=0;i<N;i++)b[i]=(com){w[i+1],0};
56     //
57     FFT(a,1);FFT(b,1);
58     for(i=0;i<N;i++)a[i]=a[i]*b[i];
59     FFT(a,-1);
60     for(i=mid+1;i<=r;i++){
61         (f[i]+=((LL)(a[i-l-1].x+0.5))%mod)%=mod;
62     }
63     solve(mid+1,r);
64     return;
65 }
66 int main(){
67     int i,j;
68     while(scanf("%d",&n)!=EOF && n){
69         memset(f,0,sizeof f);
70         for(i=1;i<=n;i++)w[i]=read()%mod;//
71         solve(1,n);
72         printf("%lld\n",f[n]%mod);
73     }
74     return 0;
75 }
时间: 2024-10-14 23:28:32

HDU5730 Shell Necklace的相关文章

HDU5730 Shell Necklace(DP + CDQ分治 + FFT)

题目 Source 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

hdu5730 Shell Necklace 【分治fft】

题目 简述: 有一段长度为n的贝壳,将其划分为若干段,给出划分为每种长度的方案数,问有多少种划分方案 题解 设\(f[i]\)表示长度为\(i\)时的方案数 不难得dp方程: \[f[i] = \sum\limits_{j=0}^{i} a[j] * f[i - j]\] 考虑转移 直接转移是\(O(n^2)\)的 如何优化? 容易发现这个转移方程非常特别,是一个卷积的形式 考虑fft 分治fft 分治fft解决的就是这样一个转移方程的快速计算的问题 \[f[i] = \sum\limits_{

HDU Shell Necklace CDQ分治+FFT

Shell Necklace 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

2016 Multi-University Training Contest 1 H.Shell Necklace

Shell Necklace Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 534    Accepted Submission(s): 227 Problem Description Perhaps the sea‘s definition of a shell is the pearl. However, in my view,

HDU 5730 - Shell Necklace

题意: 给出连续的1-n个珠子的涂色方法 a[i](1<=i<=n), 问长度为n的珠链共有多少种涂色方案 分析: 可以得到DP方程: DP[n] = ∑(i=1,n) (DP[n-i]*a[i]). 该方程为卷积形式,故 CDQ + FFT CDQ: 将 [l,r] 二分, 先得到[l,mid]的答案,再更新[l,mid]对[mid+1,r]的贡献.   对任意 DP[j](mid+1 <= j <= r), [l,mid] 对其贡献为 ∑(i=l,mid) (DP[i]*a[j

HDU 5730 Shell Necklace(CDQ分治+FFT)

[题目链接] 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(

hdu 5730 Shell Necklace fft+cdq分治

题目链接 dp[n] = sigma(a[i]*dp[n-i]), 给出a1.....an, 求dp[n]. n为1e5. 这个式子的形式显然是一个卷积, 所以可以用fft来优化一下, 但是这样也是会超时的. 所以可以用cdq分治来优化. cdq分治就是处理(l, mid)的时候, 将dp[l]...dp[mid]对dp[mid+1]...dp[r]做的贡献都算出来. #include <bits/stdc++.h> using namespace std; #define pb(x) pus

Shell Necklace (dp递推改cdq分治 + fft)

首先读出题意,然后发现这是一道DP,我们可以获得递推式为 然后就知道,不行啊,时间复杂度为O(n2),然后又可以根据递推式看出这里面可以拆解成多项式乘法,但是即使用了fft,我们还需要做n次多项式乘法,时间复杂度又变成O(n2 * log n),显然不可以.然后又利用c分治思维吧问题进行拆分问题但是,前面求出来的结果对后面的结果会产生影响,所以我们使用cdq分治思想来解决这个问题,时间复杂度变为O(n * log2n). #include<bits/stdc++.h> using namesp

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] \) 因为没有给 \( f[0] \) 赋初值,所以在递归底层令 \( f[l] += a[l] \) 注意多组数据清空数组: 读入 \( s[i] \) 时要取模!! 代码如下: #include<iostream> #include<cstdio> #include<cstr