您的位置:首页 > 运维架构 > Shell

HDU 5730: Shell Necklace 分治FFT

2018-02-24 09:39 495 查看

Shell Necklace

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

[align=left]Problem Description[/align]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.
 
[align=left]Input[/align]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.
 
[align=left]Output[/align]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). 
[align=left]Sample Input[/align]
3
1 3 7
4
2 2 2 2

[align=left]Sample Output[/align]
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.
 
[align=left]Author[/align]HIT 
[align=left]Source[/align]2016 Multi-University Training Contest 1 

递推式很显然



然而这个东西虽然是卷积 但显然不能直接FFT
所以呢 分治FFT/NTT !
具体来讲就是
每次处理区间 [l,r]
先处理 [l,mid]
对于 [l,mid] 已求出真值 处理其对 [mid+1,r] 取值的影响
之后再处理 [mid+1,r]

#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<map>
#include<set>
using namespace std;

typedef double db;
typedef long long ll;

inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=10*x+ch-'0';ch=getchar();}
return x*f;
}
void print(ll x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}

const int N=300100,mod=313;
const db pi=acos(-1);

struct cp
{
db real,image;

friend cp operator +(const cp &x,const cp &y)
{return (cp){x.real+y.real,x.image+y.image};}

friend cp operator -(const cp &x,const cp &y)
{return (cp){x.real-y.real,x.image-y.image};}

friend cp operator *(const cp &x,const cp &y)
{return (cp){x.real*y.real-x.image*y.image,x.image*y.real+x.real*y.image};}

}A
,B
;

int R
;

void fft(cp *x,int lim,int opt)
{
register int i,j,k,m;
for(i=0;i<lim;++i)
if(R[i]<i)
swap(x[i],x[R[i]]);
for(m=2;m<=lim;m<<=1)
{
k=m>>1;
cp wn=(cp){cos(2*pi*opt/m),sin(2*pi*opt/m)};
for(i=0;i<lim;i+=m)
{
cp w=(cp){1,0},tmp;
for(j=0;j<k;++j,w=w*wn)
{
tmp=x[i+j+k]*w;
x[i+j+k]=x[i+j]-tmp;
x[i+j]=x[i+j]+tmp;
}
}
}
if(opt==-1)
for(i=0;i<lim;++i)
x[i].real=x[i].real/lim+0.3;
}

int n;
int a
;
ll f
;

void cdq(int l,int r)
{
if(l==r) return ;
int mid((l+r)>>1);
cdq(l,mid);

int len(r-l),lim(1);
while(lim<=(len+mid-l)) lim<<=1;
for(int i=0;i<lim;++i)
R[i]=(i&1)*(lim>>1)+(R[i>>1]>>1),
A[i].real=A[i].image=B[i].real=B[i].image=0;
for(int i=l;i<=mid;++i) A[i-l].real=f[i];
for(int i=0;i<=len;++i) B[i].real=a[i];
fft(A,lim,1);fft(B,lim,1);
for(int i=0;i<lim;++i) A[i]=A[i]*B[i];
fft(A,lim,-1);
for(int i=mid+1;i<=r;++i)
(f[i]+=floor(A[i-l].real))%=mod;
cdq(mid+1,r);
}

int main()
{
register int i;
while(1)
{
n=read();
if(!n) break;
for(i=1;i<=n;++i)
a[i]=read()%mod;
f[0]=1;
cdq(0,n);
print(f
);
putchar('\n');
for(i=0;i<=n;++i) f[i]=0;
}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: