A * B Problem Plus

A * B Problem Plus

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1402

FFT(模板题)

(FFT的详细证明参见算法导论第三十章)

一个多项式有两种表达方式:

1.系数表示法,系数表示的多项式相乘,时间复杂度为O(n^2);

2.点值表示法,点值表示的多项式相乘,时间复杂度为O(n).

简单的说,FFT能办到的就是将系数表示的多项式转化为点值表示,其时间复杂度为O(nlgn),而将点值表示的多项式转化为系数表示需要IFFT(FFT的逆运算),其形式与FFT相似,时间复杂度也为O(nlgn).

这道题需要用FFT将两个大数转化为点值表示,相乘后再用IFFT将点值表示转化回系数表示,总时间复杂度为O(nlgn).

代码如下:

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<iostream>
 6 #define N 200005
 7 using namespace std;
 8 const double pi=acos(-1.0);
 9 struct Complex{
10     double r,i;
11     Complex(double r=0,double i=0):r(r),i(i){};
12     Complex operator + (const Complex &rhs){
13         return Complex(r+rhs.r,i+rhs.i);
14     }
15     Complex operator - (const Complex &rhs){
16         return Complex(r-rhs.r,i-rhs.i);
17     }
18     Complex operator * (const Complex &rhs){
19         return Complex(r*rhs.r-i*rhs.i,i*rhs.r+r*rhs.i);
20     }
21 }a[N],b[N],c[N];
22 char s1[N],s2[N];
23 int ans[N],n1,n2,len;
24 inline void sincos(double theta,double &p0,double &p1){
25     p0=sin(theta);
26     p1=cos(theta);
27 }
28 void FFT(Complex P[], int n, int oper){
29     for(int i=1,j=0;i<n-1;i++){
30         for(int s=n;j^=s>>=1,~j&s;);
31         if(i<j)swap(P[i],P[j]);
32     }
33     Complex unit_p0;
34     for(int d=0;(1<<d)<n;d++){
35         int m=1<<d,m2=m*2;
36         double p0=pi/m*oper;
37         sincos(p0,unit_p0.i,unit_p0.r);
38         for(int i=0;i<n;i+=m2){
39             Complex unit=1;
40             for(int j=0;j<m;j++){
41                 Complex &P1=P[i+j+m],&P2=P[i+j];
42                 Complex t=unit*P1;
43                 P1=P2-t;
44                 P2=P2+t;
45                 unit=unit*unit_p0;
46             }
47         }
48     }
49     if(oper==-1)for(int i=0;i<len;i++)P[i].r/=len;
50 }
51 void Conv(Complex a[],Complex b[],int len){//求卷积
52     FFT(a,len,1);//FFT
53     FFT(b,len,1);//FFT
54     for(int i=0;i<len;++i)c[i]=a[i]*b[i];
55     FFT(c,len,-1);//IFFT
56 }
57 void init(char *s1,char *s2){
58     len=1;
59     n1=strlen(s1),n2=strlen(s2);
60     while(len<2*n1||len<2*n2)len<<=1;
61     int idx;
62     for(idx=0;idx<n1;++idx){
63         a[idx].r=s1[n1-1-idx]-‘0‘;
64         a[idx].i=0;
65     }
66     while(idx<len){
67         a[idx].r=a[idx].i=0;
68         idx++;
69     }
70     for(idx=0;idx<n2;++idx){
71         b[idx].r=s2[n2-1-idx]-‘0‘;
72         b[idx].i=0;
73     }
74     while(idx<len){
75         b[idx].r=b[idx].i=0;
76         idx++;
77     }
78 }
79 int main(void){
80     while(scanf("%s%s",s1,s2)==2){
81         init(s1,s2);
82         Conv(a,b,len);
83         for(int i=0;i<len+len;++i)ans[i]=0;//93ms
84         //memset(ans,0,sizeof(ans));//140ms
85         int index;
86         for(index=0;index<len||ans[index];++index){
87             ans[index]+=(c[index].r+0.5);
88             ans[index+1]+=(ans[index]/10);
89             ans[index]%=10;
90         }
91         while(index>0&&!ans[index])index--;
92         for(;index>=0;--index)printf("%d",ans[index]);
93         printf("\n");
94     }
95 }
时间: 2024-10-29 04:14:01

A * B Problem Plus的相关文章

A Math Problem

A Math Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 237    Accepted Submission(s): 117 Problem Description You are given a positive integer n, please count how many positive integers

Water Problem

water problem 发布时间: 2015年10月10日 15:34   时间限制: 1000ms   内存限制: 256M 描述 题意很简单 给你N个数, Q个查询 每次查询给你一个区间[L, R] 你要找出 [L, R] 这个区间里面取模M后的最大值. 输入 第一行一个T,表示测试数据组数.第二行两个整数N, M (1<=N<=10^5, 1<=M<=10^9).第三行给你N个整数 整数范围在1到10^9之间.第四行给你一个整数Q. ( 1<=Q<=10^5)

FOJ Problem 2261 浪里个浪

                                                                                                                                                           Problem 2261 浪里个浪 Accept: 40    Submit: 106Time Limit: 1500 mSec    Memory Limit : 32768 KB Pro

XJTUOJ wmq的A&#215;B Problem FFT

wmq的A×B Problem 发布时间: 2017年4月9日 17:06   最后更新: 2017年4月9日 17:07   时间限制: 3000ms   内存限制: 512M 描述 这是一个非常简单的问题. wmq如今开始学习乘法了!他为了训练自己的乘法计算能力,写出了n个整数,并且对每两个数a,b都求出了它们的乘积a×b.现在他想知道,在求出的n(n−1)2个乘积中,除以给定的质数m余数为k(0≤k<m)的有多少个. 输入 第一行为测试数据的组数. 对于每组测试数据,第一行为2个正整数n,

hidden node and exposed node problem

Exposed node problem In wireless networks, theexposed node problem occurs when a node is prevented from sending packets to other nodes because of a neighboring transmitter. Consider an example of 4 nodes labeled R1, S1, S2, and R2, where the two rece

南阳524 A-B Problem

A-B Problem 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 A+B问题早已经被大家所熟知了,是不是很无聊呢?现在大家来做一下A-B吧. 现在有两个实数A和B,聪明的你,能不能判断出A-B的值是否等于0呢? 输入 有多组测试数据.每组数据包括两行,分别代表A和B. 它们的位数小于100,且每个数字前中可能包含+,- 号. 每个数字前面和后面都可能有多余的0. 每组测试数据后有一空行. 输出 对于每组数据,输出一行. 如果A-B=0,输出YES,否则输出NO

Lab 1: Write a java program for the triangle problem and test the program with Junit.

Tasks: 1. Install Junit(4.12), Hamcrest(1.3) with Eclipse 将两个jar包添加到工程中 2. Install Eclemma with Eclipse 3. Write a java program for the triangle problem and test the program with Junit. [Description of triangle problem]Function triangle takes three i

HDU 1016 Prime Ring Problem(DFS)

题目链接 Problem Description A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime. Note: the number of first circle should always

poj 3320 Jessica&#39;s Reading Problem(尺取法+map/hash)

题目:http://poj.org/problem?id=3320 题意:给定N个元素的数组,找出最短的一段区间使得区间里面的元素种类等于整个数组的元素种类. 分析:暴力枚举区间的起点x,然后找到最小的y,使得区间[x,y]满足条件,x向有移位后变成x',现在的y'肯定不至于在y的左边.存状态的话map和hash都可以. map代码: #include <iostream> #include <set> #include <map> #include <cstdi

hdu 5293 Tree chain problem(树链剖分+树形dp)

题目链接:hdu 5293 Tree chain problem 维护dp[u], sum[u],dp[u]表示以u为根节点的子树的最优值.sum[u]表示以u节点的所有子节点的dp[v]之和.对于边a,b,w,在LCA(a,b)节点的时候进行考虑.dp[u] = min{dp[u], Sum(a,b) - Dp(a,b) + sum[u] | (ab链上的点,不包括u } #pragma comment(linker, "/STACK:1024000000,1024000000")