洛谷 P1919 A*B Problem升级版

妈妈我终于会(A*B problem)啦~~

题目大意:

给你两个正整数 (a,b),求(a*b)

其中(a,ble 10^{1000000})

我们只要把多项式(A(x)=sumlimits_{i=0}^{n-1}a_i*x_i)(x)看作(10)就好啦~

注意输入顺序和多项式顺序相反,记得反过来

(fft),再高精乘求出每一位的系数

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define eps (1e-8)
	inline int read()
	{
		int x=0;char ch,f=1;
		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
		if(ch=='-') f=0,ch=getchar();
		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
		return f?x:-x;
	}
	const int N=5e6+10;
	const double pi=acos(-1.0);
	int n,m;
	char aa[1000010],bb[1000010];
	int limit=1,len;
	int pos[N],ret[N];
	struct complex
	{
		double x,y;
		complex(double tx=0,double ty=0){x=tx,y=ty;}
		inline complex operator + (const complex t) const
		{
			return complex(x+t.x,y+t.y);
		}
		inline complex operator - (const complex t) const
		{
			return complex(x-t.x,y-t.y);
		}
		inline complex operator * (const complex t) const
		{
			return complex(x*t.x-y*t.y,x*t.y+y*t.x);
		}
	}a[N],b[N];
	inline void fft(complex *a,int inv)
	{
		for(int i=0;i<limit;++i)
			if(i<pos[i]) swap(a[i],a[pos[i]]);
		for(int mid=1;mid<limit;mid<<=1)
		{
			complex Wn(cos(pi/mid),inv*sin(pi/mid));
			for(int r=mid<<1,j=0;j<limit;j+=r)
			{
				complex w(1,0);
				for(int k=0;k<mid;++k,w=w*Wn)
				{
					complex x=a[j+k],y=w*a[j+k+mid];
					a[j+k]=x+y;
					a[j+k+mid]=x-y;
				}
			}
		}
	}
	inline void main()
	{
		scanf("%s%s",aa,bb);
		n=strlen(aa),m=strlen(bb);
		for(int i=n-1;~i;--i) a[n-1-i].x=aa[i]-'0';
		for(int i=m-1;~i;--i) b[m-1-i].x=bb[i]-'0';
		while(limit<n+m) limit<<=1,++len;
		for(int i=0;i<limit;++i) pos[i]=(pos[i>>1]>>1)|((i&1)<<(len-1));
		fft(a,1);
		fft(b,1);
		for(int i=0;i<=limit;++i) a[i]=a[i]*b[i];
		fft(a,-1);
		
		for(int i=0;i<=limit;++i)
		{
			ret[i]+=a[i].x/limit+0.5;
			if(ret[i]>=10)
			{
				ret[i+1]+=ret[i]/10;
				ret[i]%=10;
				limit+=(i==limit);
			}
		}
		while(!ret[limit]&&limit) --limit;
		++limit;
		while(--limit>=0) putchar('0'+ret[limit]);
	}
}
signed main()
{
	red::main();
	return 0;
}
原文地址:https://www.cnblogs.com/knife-rose/p/12037381.html