zoukankan      html  css  js  c++  java
  • FTT简单入门板子

    DFT :

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cmath>
     4 #include <complex>
     5 typedef double db;
     6 typedef long long ll;
     7 
     8 #define com complex<db>
     9 using namespace std;
    10 const int N=1e5+10;
    11 const db pi=acos(-1);
    12 int n,h[N*6],M;
    13 com q[N*6],r[N*6];
    14 com a[N*6];
    15 void dft(com *src,int sig) {
    16     for (int i=0; i<M; i++) a[h[i]]=src[i]; //蝶形变换的准备
    17     for (int m=2; m<=M; m<<=1) { //正在求的组大小
    18         int half=m>>1;
    19         for (int i=0; i<half; i++) { //求A[i]与A[i+k],先枚举这个方便处理主根
    20             com w=com(cos(i*2*pi/m) , sig * sin(i*2*pi/m));
    21             //必须一步一求,不然精度会出锅。
    22             //由于转移到m,因此按照式子是m次根。
    23             for (int j=i; j<M; j+=m) { //第几组
    24                 int k=j+half;
    25                 com u=a[j], v=a[k]*w;
    26                 a[j]=u+v,a[k]=u-v;
    27             }
    28         }
    29     }
    30     for (int i=0; i<M; i++) src[i]=a[i];
    31 }
    32 int main() {
    33     //freopen("3617.in","r",stdin);
    34     cin>>n;
    35     for (int i=0; i<n; i++) scanf("%lf",&q[i].real());
    36     for (M=1; M<3*n; M<<=1);
    37     for (int i=0; i<2*n-1; i++) {
    38         if (i==n-1) r[i]=0; else 
    39         r[i]=pow(i-(n-1),-2) * (i<n-1?-1:1);
    40     }
    41     for (int i=0; i<M; i++) h[i]=(h[i>>1]>>1) + ((i&1) * (M>>1));
    42     //以次数界-1为长度,翻转二进制
    43     
    44     dft(q,1); dft(r,1);
    45     for (int i=0; i<M; i++) q[i]=q[i]*r[i];
    46     dft(q,-1);
    47     for (int i=n-1; i<n+n-1; i++) printf("%lf
    ",q[i].real() / M);
    48     //不要忘记除次数界!!!
    49 }

    NFT:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    const int N=4e5+10,mo=998244353,g=3;
    typedef long long ll;
    
    int n,m,M;
    int A[N],B[N],h[N];
    ll w[N], iw[N];
    
    ll ksm(ll x,ll y) {
        if (y==0) return 1;
        if (y==1) return x;
        ll t=ksm(x,y>>1);
        return t*t%mo*ksm(x,y&1)%mo;
    }
    void ntt(int *a,int sz,int sig) {
        for (int i = 1; i < sz; i++) 
            h[i] = (h[i>>1]>>1) + (i & 1) * (sz >> 1);
        for (int i = 0; i <sz; i++) 
            if (h[i]<i) swap(a[i],a[h[i]]);
    
        for (int m = 1; m < sz; m<<=1) {
            int td = M / (m<<1);
            for (int i = 0; i < sz; i += (m<<1)) {
                for (int j = 0; j < m; j++) {
                    ll T = a[i+j+m] * (sig == 1 ? w[td * j] : iw[td * j]) % mo;
                    a[i+j+m] = (a[i+j] - T) % mo;
                    a[i+j]   = (a[i+j] + T) % mo;
                }
            }
        }
    }
    
    int main() {
        freopen("test.in","r",stdin);
        cin>>n>>m;;
        for (int i=0; i<=n; i++) scanf("%d",&A[i]);
        for (int i=0; i<=m; i++) scanf("%d",&B[i]);
        for (M=1; M<=n+m; M<<=1);
        for (int i=1; i<M; i++) 
            h[i]=(h[i>>1]>>1) + (i&1) * (M>>1);
        ll ww = ksm(3, (mo - 1) / M);
        iw[0] = w[0] = 1;
        for (int i = 1; i < M; i++) w[i] = w[i-1] * ww % mo;
        ww = ksm(ww, mo - 2);
        for (int i = 1; i < M; i++) iw[i] = iw[i-1] * ww % mo;
    
        ntt(A,M,1);
        ntt(B,M,1);
        for (int i=0; i<M; i++) A[i]=(ll)A[i]*B[i]%mo;
        ntt(A,M,-1);
        ll cs=ksm(M,mo-2);
        for (int i=0; i<=n+m; i++) printf("%lld ",(A[i]*cs%mo+mo)%mo);
    }

     FFT:

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int maxn=270010;
    const double pi=acos(-1.0),eps=1e-4;
    struct Complex{
        double a,b;
        Complex(double a=0.0,double b=0.0):a(a),b(b){}
        Complex operator+(const Complex &x)const{return Complex(a+x.a,b+x.b);}
        Complex operator-(const Complex &x)const{return Complex(a-x.a,b-x.b);}
        Complex operator*(const Complex &x)const{return Complex(a*x.a-b*x.b,a*x.b+b*x.a);}
    }A[maxn],B[maxn];
    void FFT(Complex*,int,int);
    int n,m,N=1;
    int main(){
        scanf("%d%d",&n,&m);
        n++;m++;
        while(N<n+m)N<<=1;
        for(int i=0;i<n;i++)scanf("%lf",&A[i].a);
        for(int i=0;i<m;i++)scanf("%lf",&B[i].a);
        FFT(A,N,1);
        FFT(B,N,1);
        for(int i=0;i<N;i++)A[i]=A[i]*B[i];
        FFT(A,N,-1);
        for(int i=0;i<n+m-1;i++)printf("%d ",(int)(A[i].a+eps));
        return 0;
    }
    void FFT(Complex *A,int n,int tp){
        for(int i=1,j=0;i<n-1;i++){
            int k=N;
            do{
                k>>=1;
                j^=k;
            }while(j<k);
            if(i<j)swap(A[i],A[j]);
        }
        for(int k=2;k<=n;k<<=1){
            Complex wn(cos(-tp*2*pi/k),sin(-tp*2*pi/k));
            for(int i=0;i<n;i+=k){
                Complex w(1.0,0.0);
                for(int j=0;j<(k>>1);j++,w=w*wn){
                    Complex a(A[i+j]),b(w*A[i+j+(k>>1)]);
                    A[i+j]=a+b;
                    A[i+j+(k>>1)]=a-b;
                }
            }
        }
        if(tp<0)for(int i=0;i<n;i++)A[i].a/=n;
    }
  • 相关阅读:
    (转载)_信息安全入门指南
    经历--比赛绿盟_安全研究员
    Python正则表达式操作指南
    web 安全学习
    2014-9-10中午睡觉的一个梦
    渗透工具学习
    CVE 2013-3897
    STL 学习
    设置chrome 可以保存mht网页
    合并windows7系统下的两个IE8浏览器进程
  • 原文地址:https://www.cnblogs.com/zpj61/p/14333889.html
Copyright © 2011-2022 走看看