• hdu Shell Necklace 5730 分治FFT


    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

    题意:就是给定长度为n,然后长度为1-n的珠子有a[i]种,问拼成长度n的方案数,每种珠子有无限个。

    题解:f[i]设为拼成i的方案数,发现转移时f[i]=∑f[j]*a[i-j]+a[i] (1<=j<i)发现是个卷积的形式。

       如何去优化。

       去分治解决,设 l,mid的已经处理好了,那么,考虑l,mid对mid+1,r的贡献,

       对于l,mid的贡献部分做卷积运算,得出其贡献,加到mid,r中。

       这个过程就是CDQ的过程。

     1 #include<cstring>
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cmath>
     6 
     7 #define N 200007
     8 #define pi acos(-1)
     9 #define mod 313
    10 using namespace std;
    11 inline int read()
    12 {
    13     int x=0,f=1;char ch=getchar();
    14     while(!isdigit(ch)){if(ch=='-')f=1;ch=getchar();}
    15     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    16     return x*f;
    17 }
    18 
    19 int n,num,L;
    20 int a[N],rev[N],f[N];
    21 struct comp
    22 {
    23     double r,v;
    24     comp(double _r=0,double _v=0){r=_r;v=_v;}
    25     friend inline comp operator+(comp x,comp y){return comp(x.r+y.r,x.v+y.v);}
    26     friend inline comp operator-(comp x,comp y){return comp(x.r-y.r,x.v-y.v);}
    27     friend inline comp operator*(comp x,comp y){return comp(x.r*y.r-x.v*y.v,x.r*y.v+x.v*y.r);}
    28 }x[N],y[N];
    29 
    30 void FFT(comp *a,int f)
    31 {
    32     for (int i=1;i<num;i++)
    33         if (i<rev[i]) swap(a[i],a[rev[i]]);
    34     for (int i=1;i<num;i<<=1)
    35     {
    36         comp wn=comp(cos(pi/i),f*sin(pi/i));
    37         for (int j=0;j<num;j+=(i<<1))
    38         {
    39             comp w=comp(1,0);
    40             for (int k=0;k<i;k++,w=w*wn)
    41             {
    42                 comp x=a[j+k],y=w*a[j+k+i];
    43                 a[j+k]=x+y,a[j+k+i]=x-y;
    44             }
    45         }
    46     }
    47     if (f==-1) for (int i=0;i<num;i++) a[i].r/=num;
    48 }
    49 void CDQ(int l,int r)
    50 {
    51     if (l==r) {f[l]=(f[l]+a[l])%mod;return;}
    52     int mid=(l+r)>>1;
    53     CDQ(l,mid);
    54     L=0;for (num=1;num<=(r-l+1);num<<=1,L++);if (L) L--;
    55     for (int i=0;i<num;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<L);
    56     for (int i=1;i<num;i++) x[i]=y[i]=comp(0,0);
    57     for (int i=l;i<=mid;i++) x[i-l]=comp(f[i],0);
    58     for (int i=1;i<=r-l;i++) y[i-1]=comp(a[i],0);
    59     FFT(x,1);FFT(y,1);
    60     for (int i=0;i<num;i++) x[i]=x[i]*y[i];
    61     FFT(x,-1);
    62     for (int i=mid+1;i<=r;i++)
    63         (f[i]+=x[i-l-1].r+0.5)%=mod;
    64     CDQ(mid+1,r);
    65 }
    66 int main()
    67 {
    68     while(~scanf("%d",&n)&&n)
    69     {
    70         for (int i=1;i<=n;i++) a[i]=read()%mod,f[i]=0;
    71         CDQ(1,n);
    72         printf("%d
    ",f[n]);
    73     }
    74 }
  • 相关阅读:
    MD5加密
    HDU 1800 Flying to the Mars(Trie字典树 upper_bound)
    POJ 3624 Charm Bracelet(01背包 基础)
    hdu 1005 (规律 循环节)
    ZOJ 3710 friends(暴力 枚举 水)
    zoj 3714 Java Beans(枚举 水)
    hdu 1108 最小公倍数(数论基础 水)
    POJ 1797 Heavy Transportation(dijkstra )
    poj 3984 迷宫问题(bfs 打印路径)
    报数游戏(模拟 枚举)
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8625638.html
Copyright © 2020-2023  润新知