c++ 【模板】高精度乘法

//【模板】高精度乘法 | A*B Problem 升级版
#include<stdio.h>
#include<string.h>
typedef unsigned char byte;
typedef unsigned int word;
typedef unsigned long long ull;
typedef long long ll;
const word mod=1004535809,size=21;
char io[(1<<size)+1];
word a[1<<size],b[1<<size];
word realid[1<<size],root[1<<size],inverse[1<<size];
word i,id,floor;
ll num1,num2;
char *top;
inline ll pow(ll a,ll b){
	register ll ans=1;
	for(;b;b>>=1){
		if(b&1) (ans*=a)%=mod;
		(a*=a)%=mod;
	}
	return ans;
}
inline void loading(){
	root[0]=inverse[0]=1;
	num1=pow(3,mod>>size);
	num2=pow(num1,mod-2);
	for(i=1;i<1<<size;i++){
		root[i]=num1*root[i-1]%mod;
		inverse[i]=num2*inverse[i-1]%mod;
		for(id=i,floor=0;floor<size;floor++,id>>=1)
			realid[i]=realid[i]<<1|(id&1);
	}
}
inline void read(){
    top=io+(1<<size);
	fread(io+1,1,1<<size,stdin);
	while('0'>*top||*top>'9') top--;
	for(i=0;'0'<=*top&&*top<='9';top--,i++)
		a[realid[i]]=*top-'0';
	while('0'>*top||*top>'9') top--;	
	for(i=0;'0'<=*top&&*top<='9';top--,i++)
		b[realid[i]]=*top-'0';
} 
inline void DFT(){ 
	for(floor=0;floor<size;floor++)
		for(i=0;i<1<<size;i+=(1<<(floor+1)))
			for(id=0;id<1<<floor;id++){
				num1=a[i+id];
				num2=a[i+id+(1<<floor)];
				(num2*=root[id<<size-floor-1])%=mod;
				a[i+id]=(num1+num2)%mod;
				a[i+id+(1<<floor)]=(num1+mod-num2)%mod;
				 
				num1=b[i+id];
				num2=b[i+id+(1<<floor)];
				(num2*=root[id<<size-floor-1])%=mod;
				b[i+id]=(num1+num2)%mod;
				b[i+id+(1<<floor)]=(num1+mod-num2)%mod;
			}
}
inline void IDFT(){
	for(floor=0;floor<21;floor++)
		for(i=0;i<0x200000;i+=1<<floor+1)
			for(id=0;id<1<<floor;id++){
				num1=root[i+id];
				num2=root[i+id+(1<<floor)];
				(num2*=inverse[id<<20-floor])%=mod; 
				root[i+id]=(num1+num2)%mod;
				root[i+id+(1<<floor)]=(num1+mod-num2)%mod;
			}
}
inline void write(){
	num2=pow(1<<size,mod-2);
	top=io+(1<<size);
	num1=0;
	for(i=0;i<1<<size;i++){
		num1+=num2*root[i]%mod;
		top--;
		*top=num1%10+'0';
		num1/=10;
	}
	while(*top=='0'&&top!=io+(1<<size)) top++;
	if(top==io+(1<<size)) putchar('0');
	else fwrite(top,1,io+(1<<size)-top,stdout);
}
int main(){
	loading();
	read(); 
	DFT();
	for(i=0;i<1<<size;i++)
		root[realid[i]]=(ll)(a[i])*b[i]%mod; 
	IDFT();
	write(); 
	return 0;
}

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值