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

    随便代换一下把它变成多项式乘法,及$C[T]=sum_{i=0}^{T}A[i]×B[T-i]$这种形式,然后FFT求一下就可以啦

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define read(x) x=getint()
    using namespace std;
    const int N = 400003;
    const double Pi = acos(- 1.0);
    int getint() {
    	int k = 0, fh = 1; char c = getchar();
    	for(; c < '0' || c > '9'; c = getchar())
    		if (c == '-') fh = -1;
    	for(; c >= '0' && c <= '9'; c = getchar())
    		k = k * 10 + c - '0';
    	return k * fh;
    }
    struct cp {
    	double r, i;
    	cp (double _r = 0.0, double _i = 0.0) : r(_r), i(_i) {}
    	cp operator + (const cp &x) {return cp(r + x.r, i + x.i);}
    	cp operator - (const cp &x) {return cp(r - x.r, i - x.i);}
    	cp operator * (const cp &x) {return cp(r * x.r - i * x.i, r * x.i + i * x.r);}
    };
    cp A[N], u, t;
    int rev[N];
    void DFT(cp *a, int n, int flag) {
    	for(int i = 0; i < n; ++i) A[rev[i]] = a[i];
    	for(int i = 0; i < n; ++i) a[i] = A[i];
    	for(int m = 2; m <= n; m <<= 1) {
    		cp wn(cos(2.0 * Pi / m * flag), sin(2.0 * Pi / m * flag));
    		int mid = m >> 1;
    		for(int i = 0; i < n; i += m) {
    			cp w(1.0);
    			for(int j = 0; j < mid; ++j) {
    				u = a[i + j], t = a[i + j + mid] * w;
    				a[i + j] = u + t;
    				a[i + j + mid] = u - t;
    				w = w * wn;
    			}
    		}
    	}
    	if (flag == -1)
    		for(int i = 0; i < n; ++i)
    			a[i].r /= n;
    }
    void init(int &n) {
    	int k = 1, ret, L = 0;
    	for(; k < n; k <<= 1, ++L);
    	n = k;
    	for(int i = 0; i < n; ++i) {
    		k = i; ret = 0;
    		for(int j = 0; j < L; ++j)
    			ret <<= 1, ret |= k & 1, k >>= 1;
    		rev[i] = ret;
    	}
    }
    void FFT(int *a, int *b, int *c, int la, int lb) {
    	static cp x[N], y[N];
    	int len = la + lb - 1;
    	init(len);
    	for(int i = 0; i < len; ++i)
    		x[i].r = a[i], x[i].i = 0;
    	for(int i = 0; i < len; ++i)
    		y[i].r = b[i], y[i].i = 0;
    	DFT(x, len, 1); DFT(y, len, 1);
    	for(int i = 0; i < len; ++i)
    		x[i] = x[i] * y[i];
    	DFT(x, len, -1);
    	for(int i = 0; i < len; ++i)
    		c[i] = (int) (x[i].r + 0.5);
    }
    int x[N], y[N], a[N], n;
    int main() {
    	read(n);
    	for(int i = 0; i < n; ++i)
    		read(x[i]), read(y[i]);
    	for(int i = 0; i < n; ++i)
    		a[i] = x[n - i - 1];
    	FFT(y, a, x, n, n);
    	for(int i = 0; i < n; ++i)
    		a[i] = x[n - i - 1];
    	for(int i = 0; i < n; ++i)
    		printf("%d
    ", a[i]);
    	return 0;
    }
    

    233

  • 相关阅读:
    编写代码的「八荣八耻」- 以用户易用为荣,以复杂歧义为耻
    《跃迁-成为高手的技术》之联机学习
    《跃迁-成为高手的技术》感悟
    JAVA SPI(Service Provider Interface)原理、设计及源码解析(其一)
    测试了一下编解码的执行效果
    谈面试中的亮点
    稳定性「三十六计」实战和背后的逻辑
    Python,Jupyter Notebook,IPython快速安装教程
    Python多进程编程
    R语言基础:数组&列表&向量&矩阵&因子&数据框
  • 原文地址:https://www.cnblogs.com/abclzr/p/5432541.html
Copyright © 2011-2022 走看看