zoukankan      html  css  js  c++  java
  • BZOJ 2194 快速傅里叶之二

    2194: 快速傅立叶之二

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 1471  Solved: 855
    [Submit][Status][Discuss]

    Description

    请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5。 a,b中的元素均为小于等于100的非负整数。

    Input

    第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a[i],b[i] (0 < = i < N)。

    Output

    输出N行,每行一个整数,第i行输出C[i-1]。

    Sample Input

    5
    3 1
    2 4
    1 1
    2 4
    1 4

    Sample Output

    24
    12
    10
    6
    1

    HINT

    Source

    和上题一样啊,脑补一下小结论

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    typedef complex <double> E;
    inline int read(){
        int x=0;int f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int MAXN=1e6+10;
    const double pi=acos(-1);
    int n,m,R[MAXN],L,H;
    E a[MAXN],b[MAXN],w[MAXN],k;
    inline void FFT(E *a,int f){
        for(int i=0;i<L;i++){
            if(i<R[i]) swap(a[i],a[R[i]]);
        }
            for(int len=2;len<=L;len<<=1){
                int l=len>>1;
                E wn(cos(pi/l),f*sin(pi/l));
                for(int i=1;i<l;i++) w[i]=w[i-1]*wn;
                for(int st=0;st<L;st+=len){
                    for(int k=0;k<l;k++){
                        E x=a[st+k];E y=w[k]*a[st+k+l];
                        a[st+k]=x+y;a[st+k+l]=x-y;
                    }
                }
            }
        if(f==-1){
            for(int i=0;i<L;i++){
                a[i]/=L;
            }
        }
    }
    int main(){
        //freopen("All.in","r",stdin);
        //freopen("bai.out","w",stdout);
        n=read();w[0].real()=1;
        for(int i=0;i<n;i++){
            a[i]=read();b[n-i-1]=read();
        }
        L=1;
        while(L<2*n) L<<=1,H++;
        for(int i=0;i<L;i++){
            R[i]=(R[i>>1]>>1)|((i&1)<<(H-1));
        }
        FFT(a,1);FFT(b,1);
        for(int i=0;i<L;i++) a[i]=a[i]*b[i];
        FFT(a,-1);
        for(int i=0;i<n;i++) printf("%d
    ",int(a[i+n-1].real()+0.5));
        return 0;
    }
    

    对拍代码

    #include <bits/stdc++.h>
    using namespace std;
    int main(){
    	srand(time(int(NULL)));
        freopen("All.in","w",stdout);
        int n=rand()%10007;int m=rand()%10007;
        cout<<n<<' '<<m<<endl;
        for(int i=0;i<n;i++){
            printf("%d
    ",rand()%17+2);
        }
        for(int i=0;i<m;i++){
            printf("%d
    ",rand()%17+2);
        }
        return 0;
    }
    

      

  • 相关阅读:
    C#.NET常见问题(FAQ)-浮点数如何四舍五入
    C#.NET常见问题(FAQ)-方法参数带ref是什么意思
    C#.NET常见问题(FAQ)-list比数组效率低多少
    C#.NET常见问题(FAQ)-如何输出带选项的MessageBox,YESNO
    微软企业库Unity学习笔记
    微软企业库5.0---缓存模块
    学习微软企业库--日志模块
    学习微软企业库存心得--总结
    C#获取网页内容,并且处理正确编码
    C#获取网页内容的三种方式
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/7894405.html
Copyright © 2011-2022 走看看