zoukankan      html  css  js  c++  java
  • 【CodeVS 3123】高精度练习之超大整数乘法 &【BZOJ 2197】FFT快速傅立叶

    第一次写法法塔,,,感到威力无穷啊

    看了一上午算导就当我看懂了?PS:要是机房里能有个清净的看书环境就好了

    FFT主要是用了巧妙的复数单位根,复数单位根在复平面上的对称性使得快速傅立叶变换的时间复杂度空降为O(nlogn)←个人的愚蠢理解请随意吐槽

    具体的我就不说了,算导上都说得很清楚,说得好像有人会听我说什么似的

    模板在这里↓

    CodeVS 3123:

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 1E6 + 3;
    const double Pi = acos(- 1.0);
    struct cp {
    	double r, i;
    	cp(double _r = 0.0, double _i = 0.0) : r(_r), i(_i) {}
    	cp operator + (const cp &x) const {return cp(r + x.r, i + x.i);}
    	cp operator - (const cp &x) const {return cp(r - x.r, i - x.i);}
    	cp operator * (const cp &x) const {return cp(r * x.r - i * x.i, r * x.i + i * x.r);}
    };
    char s[N];
    int rev[N];
    cp A[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, mid; m <= n; m <<= 1) {
    		cp wn(cos(2.0 * Pi / m * flag), sin(2.0 * Pi / m * flag));
    		mid = m >> 1;
    		for(int i = 0; i < n; i += m) {
    			cp w(1.0);
    			for(int j = 0; j < mid; ++j) {
    				cp u = a[i + j + mid] * w, t = a[i + j];
    				a[i + j] = t + u;
    				a[i + j + mid] = t - u;
    				w = w * wn;
    			}
    		}
    	}
    	if (flag == -1)
    		for(int i = 0; i < n; ++i)
    			a[i].r /= n;
    }
    
    void in(cp *a, int &n) {
    	scanf("%s", s);
    	n = strlen(s);
    	for(int i = 0; i < n; ++i)
    		a[i].r = s[n - i - 1] - '0';
    }
    void init(int &n) {
    	int k = 1, L = 0;
    	for(; k < n; k <<= 1, ++L);
    	n = k;
    	for(int i = 0; i < n; ++i) {
    		int t = i, ret = 0;
    		for(int j = 0; j < L; ++j)
    			ret <<= 1, ret |= (t & 1), t >>= 1;
    		rev[i] = ret;
    	}
    }
    cp a[N], b[N];
    int len = -1, n, ans[N];
    void FFT() {
    	DFT(a, len, 1); DFT(b, len, 1);
    	for(int i = 0; i < len; ++i)
    		a[i] = a[i] * b[i];
    	DFT(a, len, -1);
    }
    int main() {
    	in(a, n); len += n;
    	in(b, n); len += n;
    	init(len);
    	FFT();
    	for(int i = 0; i < len; ++i)
    		ans[i] = (int) (a[i].r + 0.5);
    	for(int i = 0; i < len; ++i)
    		ans[i + 1] += ans[i] / 10, ans[i] %= 10;
    	for(++len; ans[len] == 0 && len > 0; --len);
    	for(int i = len; i >= 0; --i)
    		printf("%d", ans[i]);
    	puts("");
    	return 0;
    }
    

    BZOJ 2197顺便水一水~:

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 1E6 + 3;
    const double Pi = acos(- 1.0);
    struct cp {
    	double r, i;
    	cp(double _r = 0.0, double _i = 0.0) : r(_r), i(_i) {}
    	cp operator + (const cp &x) const {return cp(r + x.r, i + x.i);}
    	cp operator - (const cp &x) const {return cp(r - x.r, i - x.i);}
    	cp operator * (const cp &x) const {return cp(r * x.r - i * x.i, r * x.i + i * x.r);}
    };
    char s[N];
    int rev[N];
    cp A[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, mid; m <= n; m <<= 1) {
    		cp wn(cos(2.0 * Pi / m * flag), sin(2.0 * Pi / m * flag));
    		mid = m >> 1;
    		for(int i = 0; i < n; i += m) {
    			cp w(1.0);
    			for(int j = 0; j < mid; ++j) {
    				cp u = a[i + j + mid] * w, t = a[i + j];
    				a[i + j] = t + u;
    				a[i + j + mid] = t - u;
    				w = w * wn;
    			}
    		}
    	}
    	if (flag == -1)
    		for(int i = 0; i < n; ++i)
    			a[i].r /= n;
    }
    
    void in(cp *a, int &n) {
    	scanf("%s", s);
    	n = strlen(s);
    	for(int i = 0; i < n; ++i)
    		a[i].r = s[n - i - 1] - '0';
    }
    void init(int &n) {
    	int k = 1, L = 0;
    	for(; k < n; k <<= 1, ++L);
    	n = k;
    	for(int i = 0; i < n; ++i) {
    		int t = i, ret = 0;
    		for(int j = 0; j < L; ++j)
    			ret <<= 1, ret |= (t & 1), t >>= 1;
    		rev[i] = ret;
    	}
    }
    cp a[N], b[N];
    int len = -1, n, ans[N];
    void FFT() {
    	DFT(a, len, 1); DFT(b, len, 1);
    	for(int i = 0; i < len; ++i)
    		a[i] = a[i] * b[i];
    	DFT(a, len, -1);
    }
    int main() {
    	scanf("%d
    ", &len); len = (len << 1) - 1;
    	in(a, n);
    	in(b, n);
    	init(len);
    	FFT();
    	for(int i = 0; i < len; ++i)
    		ans[i] = (int) (a[i].r + 0.5);
    	for(int i = 0; i < len; ++i)
    		ans[i + 1] += ans[i] / 10, ans[i] %= 10;
    	for(++len; ans[len] == 0 && len > 0; --len);
    	for(int i = len; i >= 0; --i)
    		printf("%d", ans[i]);
    	puts("");
    	return 0;
    }
    

    高一下半学期开学前的晚上就在看这个东西,拖到现在才理解,累啊~

  • 相关阅读:
    python模块--time模块
    python模块--如何相互调用自己写的模块
    Animating Views Using Scenes and Transitions
    fragment 切换
    android textview 设置text 字体
    android intent 5.1
    android EditView ime
    animation of android (4)
    animation of android (3)
    animation of android (2)
  • 原文地址:https://www.cnblogs.com/abclzr/p/5431774.html
Copyright © 2011-2022 走看看