zoukankan      html  css  js  c++  java
  • [hdu1402]A * B Problem Plus(FFT模板题)

    解题关键:快速傅里叶变换fft练习。

    关于结果多项式长度的确定,首先将短多项式扩展为长多项式,然后扩展为两倍。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<iostream>
    #include<cmath>
    #include<complex>
    #define N 131072
    #define pi acos(-1.0)
    using namespace std;
    typedef long long ll;
    typedef complex<double> E;
    int n,m,L;
    char ch1[N],ch2[N];
    int R[N],c[N];
    E a[N],b[N];
    //高效迭代实现fft
    void fft(E *a,int f){
        for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);//位逆序置换
        for(int i=1;i<n;i<<=1){
            E wn(cos(pi/i),f*sin(pi/i));
            for(int j=0;j<n;j+=(i<<1)){
                E w(1,0);
                for(int k=0;k<i;k++,w*=wn){//蝴蝶操作
                    E x=a[j+k],y=w*a[j+k+i];
                    a[j+k]=x+y;a[j+k+i]=x-y;
                }
            }
        }
        if(f==-1)for(int i=0;i<n;i++)a[i]/=n;
    }
    
    int main(){
        while(scanf("%s%s",ch1,ch2)!=EOF){
            memset(a,0,sizeof a);
            memset(b,0,sizeof b);
            memset(c,0,sizeof c);
            L=0;
            int len1=strlen(ch1),len2=strlen(ch2);
            for(int i=0;i<len1;i++)a[i]=ch1[len1-i-1]-'0';
            for(int i=0;i<len2;i++)b[i]=ch2[len2-i-1]-'0';
            for(n=1;n<2*len1||n<2*len2;n<<=1)L++;
            for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));//打印逆序表
            fft(a,1);fft(b,1);//dft
            for(int i=0;i<n;i++)a[i]*=b[i];
            fft(a,-1);//idft
            for(int i=0;i<n;i++)c[i]=(int)(a[i].real()+0.1);
            for(int i=0;i<n;i++)
                if(c[i]>=10){
                    c[i+1]+=c[i]/10,c[i]%=10;
                }
            while(n>0&&!c[n]) n--;
            for(;n>=0;--n) printf("%d",c[n]);
            puts("");
        }
        return 0;
    }

     memset改一下。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<iostream>
    #include<cmath>
    #include<complex>
    #define N 131072
    #define pi acos(-1.0)
    using namespace std;
    typedef long long ll;
    typedef complex<double> E;
    int n,m,L;
    char ch1[N],ch2[N];
    int R[N],c[N];
    E a[N],b[N];
    //高效迭代实现fft
    void fft(E *a,int f){
        for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);//位逆序置换
        for(int i=1;i<n;i<<=1){
            E wn(cos(pi/i),f*sin(pi/i));
            for(int j=0;j<n;j+=(i<<1)){
                E w(1,0);
                for(int k=0;k<i;k++,w*=wn){//蝴蝶操作
                    E x=a[j+k],y=w*a[j+k+i];
                    a[j+k]=x+y;a[j+k+i]=x-y;
                }
            }
        }
        if(f==-1)for(int i=0;i<n;i++)a[i]/=n;
    }
    
    int main(){
        while(scanf("%s%s",ch1,ch2)!=EOF){
            memset(c,0,sizeof c);
            int len1=strlen(ch1),len2=strlen(ch2);
            L=0;
            for(n=1;n<2*len1||n<2*len2;n<<=1)L++;
            for(int i=0;i<n;i++) a[i]=b[i]=0;
            for(int i=0;i<len1;i++)a[i]=ch1[len1-i-1]-'0';
            for(int i=0;i<len2;i++)b[i]=ch2[len2-i-1]-'0';
            for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));//打印逆序表
            fft(a,1);fft(b,1);//dft
            for(int i=0;i<n;i++)a[i]*=b[i];
            fft(a,-1);//idft
            for(int i=0;i<n;i++)c[i]=(int)(a[i].real()+0.1);
            for(int i=0;i<n;i++)
                if(c[i]>=10){
                    c[i+1]+=c[i]/10,c[i]%=10;
                }
            while(n>0&&!c[n]) n--;
            for(;n>=0;--n) printf("%d",c[n]);
            puts("");
        }
        return 0;
    }

     最后试了下,len1+len2就可以。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<iostream>
    #include<cmath>
    #include<complex>
    #define N 131072
    #define pi acos(-1.0)
    using namespace std;
    typedef long long ll;
    typedef complex<double> E;
    int n,m,L;
    char ch1[N],ch2[N];
    int R[N],c[N];
    E a[N],b[N];
    //高效迭代实现fft
    void fft(E *a,int f){
        for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);//位逆序置换
        for(int i=1;i<n;i<<=1){
            E wn(cos(pi/i),f*sin(pi/i));
            for(int j=0;j<n;j+=(i<<1)){
                E w(1,0);
                for(int k=0;k<i;k++,w*=wn){//蝴蝶操作
                    E x=a[j+k],y=w*a[j+k+i];
                    a[j+k]=x+y;a[j+k+i]=x-y;
                }
            }
        }
        if(f==-1)for(int i=0;i<n;i++)a[i]/=n;
    }
    
    int main(){
        while(scanf("%s%s",ch1,ch2)!=EOF){
            memset(c,0,sizeof c);
            int len1=strlen(ch1),len2=strlen(ch2);
            L=0;
            for(n=1;n<len1+len2;n<<=1)L++;
            for(int i=0;i<=n;i++) a[i]=b[i]=0;
            for(int i=0;i<len1;i++)a[i]=ch1[len1-i-1]-'0';
            for(int i=0;i<len2;i++)b[i]=ch2[len2-i-1]-'0';
            for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));//打印逆序表
            fft(a,1);fft(b,1);//dft
            for(int i=0;i<n;i++)a[i]*=b[i];
            fft(a,-1);//idft
            for(int i=0;i<n;i++)c[i]=(int)(a[i].real()+0.1);
            for(int i=0;i<n;i++)
                if(c[i]>=10){
                    c[i+1]+=c[i]/10,c[i]%=10;
                }
            while(n>0&&!c[n]) n--;
            for(;n>=0;--n) printf("%d",c[n]);
            puts("");
        }
        return 0;
    }
  • 相关阅读:
    Oracle通过Rman的"copy datafile"转移数据文件后不要使用sqlplus来重命名文件位置和文件名
    Oracle使用errorstack跟踪客户端的ORA报错
    Oracle OEM 13C表空间报警延迟问题
    CH5 用神经网络解决线性问题
    CH4 简化神经网络模型
    CH3 初识 TensorFlow
    Python 语言和 TensorFlow 框架环境准备
    创建型模式之单例模式与工厂模式(一)
    Node.js Koa框架学习笔记
    国庆七天假 不如来学学Vue-Router
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7868285.html
Copyright © 2011-2022 走看看