zoukankan      html  css  js  c++  java
  • FFT

    所谓fft,只是一种快速的插值技术,我们知道,朴素的多项式乘法是N^2的。我们又知道,一个多项式可以由N个的点值来表示。那么N个点相乘,可以在O(N)内得出,fft所提供的,只是快速插值和求系数而已。

    我们知道 欧拉定理, e的复数次幂满足很多优秀的性质,我们用这些性质快速求值即可。

    http://www.gatevin.moe/acm/fft%E7%AE%97%E6%B3%95%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/

    #include<bits/stdc++.h>
    #define db double
    #define fo(i,a,b) for(int i=a;i<=b;i++)
    #define pi acos(-1)
    #define N 3378123
    #define com rrsb
    using namespace std;
    struct com{  //定义复数
        db r,i;
        com(){}
        com(db a,db b):r(a),i(b){}
    };
    inline com operator + (const com A,const com B) {
            return com(A.r+B.r,A.i+B.i);
        }
    inline com operator - (const com A,const com B) {
            return com(A.r-B.r,A.i-B.i);
        }
    inline com operator * (const com A,const com B) {
            return com(A.r*B.r-A.i*B.i,A.i*B.r+A.r*B.i);
        }
    com a[N],b[N],X,Y;
    int c[N],R[N],n,m,L;
    char ch[N];
    bool bo;
    inline int read(){
        int f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    inline void fft(com *a,int x){
        fo(i,0,n-1) if(i < R[i]) swap(a[i],a[R[i]]);
        for (int i=1;i<n;i<<=1)// 注意这里的n不是输入的n
         { com wn(cos(pi/i),x*sin(pi/i));  //wn为旋转因子
          for (int j=0;j<n;j+=(i<<1)){//蝴蝶操作减小常熟
              com w(1,0);
               for (int k=0;k<i;k++,w=w*wn) {
                   X=a[j+k]; Y=w*a[j+k+i];
                   a[j+k]=X+Y; a[i+j+k]=X-Y;
               }
          }
        }
        if (x==-1) fo(i,0,n-1) a[i].r=a[i].r/n;// 求系数要除n
    }
    int main () {
        //0freopen("a.in","r",stdin);
        n=read();m=read();
        for(int i=0;i<=n;i++)a[i].r=read();
        for(int i=0;i<=m;i++)b[i].r=read(); m+=n;
        for(n = 1;n <= m ;n <<= 1) ++L;// get size 
        fo(i,0,n-1) R[i] = (R[i>>1]>>1)|((i&1)<<(L-1));// 二进制下将位翻转
        fft(a,1); fft(b,1);//求点值
        fo(i,0,n) a[i]=a[i]*b[i];//点乘
        fft(a,-1);//求系数
        fo(i,0,m) c[i]=(int)(a[i].r+0.5);
        fo(i,0,m) printf("%d ",c[i]);
        return 0;
    }
  • 相关阅读:
    文件上传漏洞总结篇
    python 构造mysql爆破器
    python写exploit采集器
    文件包含漏洞总结
    python Flask篇(一)
    Python写一个目录检索器
    python爬搜狗微信获取指定微信公众号的文章
    python打造文件包含漏洞检测工具
    python打造漏洞补丁缺少检测
    表单
  • 原文地址:https://www.cnblogs.com/rrsb/p/7944340.html
Copyright © 2011-2022 走看看