zoukankan      html  css  js  c++  java
  • [BZOJ2179]FFT快速傅立叶

    [BZOJ2179]FFT快速傅立叶

    试题描述

    给出两个n位10进制整数x和y,你需要计算x*y。

    输入

    第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。

    输出

    输出一行,即x*y的结果。

    输入示例

    1
    3
    4

    输出示例

    12

    数据规模及约定

    n<=60000

    题解

    可以把一个数看成一个多项式,乘起来之后处理一下进位即可。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
    	if(Head == Tail) {
    		int l = fread(buffer, 1, BufferSize, stdin);
    		Tail = (Head = buffer) + l;
    	}
    	return *Head++;
    }
    int read() {
    	int x = 0, f = 1; char c = Getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
    	return x * f;
    }
    
    #define maxn 240010
    const double pi = acos(-1.0);
    int n;
    struct Complex {
    	double a, b;
    	Complex operator + (const Complex& t) {
    		Complex ans;
    		ans.a = a + t.a;
    		ans.b = b + t.b;
    		return ans;
    	}
    	Complex operator - (const Complex& t) {
    		Complex ans;
    		ans.a = a - t.a;
    		ans.b = b - t.b;
    		return ans;
    	}
    	Complex operator * (const Complex& t) {
    		Complex ans;
    		ans.a = a * t.a - b * t.b;
    		ans.b = a * t.b + b * t.a;
    		return ans;
    	}
    	Complex operator *= (const Complex& t) {
    		*this = *this * t;
    		return *this;
    	}
    } a[maxn], b[maxn];
    
    char A[(maxn>>2)+10], B[(maxn>>2)+10];
    int Ord[maxn], num[maxn];
    void FFT(Complex* x, int n, int tp) {
    	for(int i = 0; i < n; i++) if(i < Ord[i]) swap(x[i], x[Ord[i]]);
    	for(int i = 1; i < n; i <<= 1) {
    		Complex wn, w; wn.a = cos(pi / i); wn.b = tp * sin(pi / i);
    		for(int j = 0; j < n; j += (i << 1)) {
    			w.a = 1.0; w.b = 0.0;
    			for(int k = 0; k < i; k++) {
    				Complex t1 = x[j+k], t2 = w * x[j+k+i];
    				x[j+k] = t1 + t2;
    				x[j+k+i] = t1 - t2;
    				w *= wn;
    			}
    		}
    	}
    	return ;
    }
    
    int main() {
    	n = read();
    	char tc = Getchar();
    	while(!isdigit(tc)) tc = Getchar();
    	for(int i = 0; i < n; i++) A[i] = tc, tc = Getchar();
    	while(!isdigit(tc)) tc = Getchar();
    	for(int i = 0; i < n; i++) {
    		B[i] = tc;
    		if(i < n - 1) tc = Getchar();
    	}
    	for(int i = n - 1; i >= 0; i--) {
    		a[n-1-i].a = (double)(A[i] - '0'); a[i].b = 0.0;
    		b[n-1-i].a = (double)(B[i] - '0'); b[i].b = 0.0;
    	}
    	
    	int m = (n - 1) * 2, L = 0;
    	for(n = 1; n <= m; n <<= 1) L++;
    	for(int i = 0; i < n; i++) Ord[i] = (Ord[i>>1] >> 1) | ((i & 1) << L - 1);
    	FFT(a, n, 1); FFT(b, n, 1);
    	for(int i = 0; i <= n; i++) a[i] *= b[i];
    	FFT(a, n, -1);
    	for(int i = 0; i <= n; i++) {
    		int x = (int)(a[i].a / n + .5);
    		num[i] += x;
    		num[i+1] += num[i] / 10;
    		num[i] %= 10;
    	}
    	
    	int i = n;
    	for(; !num[i]; i--) ;
    	for(; i >= 0; i--) putchar(num[i] + '0'); putchar('
    ');
    	
    	return 0;
    }
    
  • 相关阅读:
    (转载)_信息安全入门指南
    经历--比赛绿盟_安全研究员
    Python正则表达式操作指南
    web 安全学习
    2014-9-10中午睡觉的一个梦
    渗透工具学习
    CVE 2013-3897
    STL 学习
    设置chrome 可以保存mht网页
    合并windows7系统下的两个IE8浏览器进程
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5727927.html
Copyright © 2011-2022 走看看