zoukankan      html  css  js  c++  java
  • FFT P3803 [模板]多项式乘法

    FFT(快速傅里叶变化) 可以加速求多项式乘法。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<map>
    #include<queue>
    #include<vector>
    
    using namespace std;
    typedef long long ll;
    const int N = 4e6 + 105;
    const int mod = 1e9 + 7;
    const double Pi = acos(- 1.0);
    const ll INF = 1e16;
    
    inline int read() {
        char ch = getchar(); int x = 0, f = 1;
        while (ch < '0' || ch > '9') {
            if (ch == '-') f = -1;
    	ch = getchar();
        }
        while ('0' <= ch && ch <= '9') {
    	x = x * 10 + ch - '0';
    	ch = getchar();
        } 
        return x * f;
    }
    
    struct complex {
        double x, y;
        complex (double xx = 0, double yy = 0) {x = xx, y = yy;}
    } a[N], b[N];
    
    complex operator + (complex a, complex b) { return complex(a.x + b.x , a.y + b.y);}
    complex operator - (complex a, complex b) { return complex(a.x - b.x , a.y - b.y);}
    complex operator * (complex a, complex b) { return complex(a.x * b.x - a.y * b.y , a.x * b.y + a.y * b.x);} 
    
    int l, r[N];
    int len = 1;
    
    void FFT(complex a[], int inv){
        for(int i = 0; i < len; ++ i)
    	if(i < r[i]) 
    	    swap(a[i], a[r[i]]);
    	
        complex w, Wn, x, y;
    	
        for(int mid = 1; mid < len; mid <<= 1){		
    	Wn.x = cos(Pi / mid) , Wn.y = inv * sin(Pi / mid);
    	for(int Size = mid << 1, L = 0; L < len; L += Size){	
    	    w.x = 1, w.y = 0;
    	    for(int i = 0; i < mid; i ++, w = w * Wn){   
    		x = a[L + i], y = w * a[L + mid + i];
    		a[L + i] = x + y;
    		a[L + mid + i] = x - y;
    	    }
    	}
        }
    }
    
    
    int main()
    {
        int n, m;
        n = read(), m = read();
        for(int i = 0; i <= n; ++ i) a[i].x = read();
        for(int i = 0; i <= m; ++ i) b[i].x = read();
    
        while(len <= n + m) len <<= 1, l ++;
        for(int i = 0; i < len; ++ i)
    	r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
    
        FFT(a, 1), FFT(b, 1);	
        for(int i = 0; i <= len; ++ i) a[i] = a[i] * b[i];
        FFT(a, -1);		
        for(int i = 0; i <= n + m ; ++ i){
            printf("%d ",(int)(a[i].x / len + 0.5));
        }
        return 0;
    }
    
    
  • 相关阅读:
    关于多态的一些问题
    003 关于shell基础,大数据的前期准备
    002 在大数据中基础的llinux基本命令
    013 MapReduce八股文的wordcount应用
    接口里语句的修饰问题
    Apache Rewrite url重定向功能的简单配置
    学习笔记 --- 缓存、动态页面静态化、网站优化
    使用PHP连接、操纵Memcached的原理和教程
    Apache中关于页面缓存的设置
    缓存(之一) 使用Apache Httpd实现http缓存
  • 原文地址:https://www.cnblogs.com/A-sc/p/12741388.html
Copyright © 2011-2022 走看看