zoukankan      html  css  js  c++  java
  • hdu 5730 Shell Necklace 分治FFT

    Shell Necklace

    题目连接:

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

    enter image description here
    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.

    题意

    题解:

    推出显然的公式
    (dp[i]= sum_{j=0}^{i-1}(dp[j]*a[i-j]))
    也就是分治fft的经典形式

    cdq(l,r)先算出前一半的真实dp值,后一半加上前一半的贡献,再递归后一半
    每次操作为区间长度*log,总的复杂度nloglog

    代码

    //#include <bits/stdc++.h>
    #include <stdio.h>
    #include <iostream>
    #include <string.h>
    #include <math.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <set>
    #include <map>
    #include <stack>
    #include <bitset>
    #include <string>
    #include <time.h>
    using namespace std;
    long double esp=1e-11;
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #define fi first
    #define se second
    #define all(a) (a).begin(),(a).end()
    #define cle(a) while(!a.empty())a.pop()
    #define mem(p,c) memset(p,c,sizeof(p))
    #define mp(A, B) make_pair(A, B)
    #define pb push_back
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    typedef long long int LL;
    const long double PI = acos((long double)-1);
    const LL INF=0x3f3f3f3fll;
    const int MOD = 313ll;
    const int maxn=300000;
    struct complex{
        double r,i;
        complex(double _r = 0.0,double _i = 0.0){r = _r; i = _i;}
        complex operator +(const complex &b){return complex(r+b.r,i+b.i);}
        complex operator -(const complex &b){return complex(r-b.r,i-b.i);}
        complex operator *(const complex &b){return complex(r*b.r-i*b.i,r*b.i+i*b.r);}
    };
    void change(complex y[],int len){
        int i,j,k;
        for(i = 1, j = len/2;i < len-1; i++){
            if(i < j)swap(y[i],y[j]);
            k = len/2;
            while( j >= k){
                j -= k;
                k /= 2;
            }
            if(j < k) j += k;
        }
    }
    void FFT(complex y[],int len,int on){  //len=2^k
        change(y,len);
        for(int h = 2; h <= len; h <<= 1){
            complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
            for(int j = 0;j < len;j+=h){
                complex w(1,0);
                for(int k = j;k < j+h/2;k++){
                    complex u = y[k];
                    complex t = w*y[k+h/2];
                    y[k] = u+t;
                    y[k+h/2] = u-t;
                    w = w*wn;
                }
            }
        }
        if(on == -1)
            for(int i = 0;i < len;i++)
                y[i].r /= len;
    }
    int callen(int len1,int len2){
        int len=1;
        while(len < len1*2 || len < len2*2)len<<=1;
        return len;
    }
    complex tf1[maxn],tf2[maxn];   //0~len1+len2-1,fftans[i] = y1[i] * y2[i]
    int fftans[maxn];
    void fft(int* y1,int len1,int* y2,int len2){ //0~len1-1,0~len2-1
        int len=callen(len1,len2);
        for(int i = 0;i < len1;i++)
            tf1[i] = complex(y1[i],0);
        for(int i = len1;i < len;i++)
            tf1[i] = complex(0,0);
        for(int i = 0;i < len2;i++)
            tf2[i] = complex(y2[i],0);
        for(int i = len2;i < len;i++)
            tf2[i] = complex(0,0);
        FFT(tf1,len,1);
        FFT(tf2,len,1);
        for(int i = 0;i < len;i++)
            tf1[i] = tf1[i]*tf2[i];
        FFT(tf1,len,-1);
        for(int i = 0;i < len1+len2-1;i++)
            fftans[i] = tf1[i].r+0.5;
    }
    int A[maxn],Ans[maxn];
    void solve(int l,int r){
        int m=(l+r)>>1;
        fft(Ans+l,m-l+1,A,r-l+1);
        for(int i = m-l+1;i <=r-l;i++)
            Ans[i+l]=(Ans[i+l]+fftans[i])%MOD;
    }
    void CDQ(int L,int R){
        if(L==R)return;
        int m=(L+R)>>1;
        CDQ(L,m);
        solve(L,R);
        CDQ(m+1,R);
    }
    int main()
    {
        //freopen("in.txt", "r", stdin);
        //freopen("inlay.in", "r", stdin);
        //freopen("out.txt", "w", stdout);      %I64d
        //vector<int>::iterator iter;
        //memset(m,0,sizeof(int));
        //for(int x=1;x<=n;x++)
        //for(int y=1;y<=n;y++)
        //scanf("%d",&a);
        //printf("%d
    ",ans);
        while(1)
        {
            int n;
            scanf("%d",&n);
            if(n==0)break;
            memset(Ans,0,(callen(n,n)+10)*sizeof(int));
            Ans[0]=1;
            memset(A,0,(callen(n,n)+10)*sizeof(int));
            for(int x=1;x<=n;x++)
            {
                scanf("%d",&A[x]);
                A[x]%=MOD;
            }
            CDQ(0,n);
            printf("%d
    ",(Ans[n]+MOD)%MOD);
        }
        return 0;
    }
  • 相关阅读:
    实用机器学习 跟李沐学AI
    Explicitly drop temp table or let SQL Server handle it
    dotnettransformxdt and FatAntelope
    QQ拼音输入法 禁用模糊音
    (技术八卦)Java VS RoR
    Ruby on rails开发从头来(windows)(七)创建在线购物页面
    Ruby on rails开发从头来(windows)(十三)订单(Order)
    Ruby on rails开发从头来(windows)(十一)订单(Order)
    新员工自缢身亡,华为又站到了风口浪尖
    死亡汽油弹(Napalm Death)乐队的视频和来中国演出的消息
  • 原文地址:https://www.cnblogs.com/femsub/p/5723297.html
Copyright © 2011-2022 走看看