【法法塔】【FFT】【快速傅里叶离散变化】luogu P1919 P3803

本文介绍了一种使用快速傅里叶变换(FFT)进行多项式乘法的方法。通过迭代实现,利用C++编程语言详细展示了如何进行多项式的快速乘法运算。此方法能够高效地解决大数相乘的问题,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

迭代实现
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<set>
#include<map>
#include<cmath>
#include<sstream>
#include<queue>
#include<vector>
#include<deque>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
const double pi=acos(-1);
const int MAXN=1e7+11;
#define For(a,b,c) for (ll (a)=(b);(a)<(c);(a)++)
#define foreach(iter,V) for (__typeof((V).begin()) iter=(V).begin();iter!=(V).end();iter++)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
struct cp{
    double x,y;
    cp(){}
    cp(double nx,double ny){
        x=nx;y=ny;
    }
    cp operator + (cp &a)	{return cp(a.x+x,a.y+y);}
    cp operator - (cp &a)	{return cp(x-a.x,y-a.y);}
    cp operator * (cp &a)	{return cp(a.x*x-a.y*y,a.x*y+a.y*x);}
}a[MAXN],b[MAXN];
ll limit,l,r[MAXN];
void fast_fast_tle(cp *A,ll type){	
    For(i,0,limit)	if (i<r[i])	swap(A[i],A[r[i]]);
    for (int mid=1;mid<limit;mid*=2){
        cp Wn=cp(cos(pi/mid),type*sin(pi/mid));
        int r=mid*2;
        for (int j=0;j<limit;j+=r){
            cp w=cp(1,0);
            for (int k=0;k<mid;k++,w=w*Wn){
                cp t=w*A[j+mid+k];
                A[j+mid+k]=A[j+k]-t;
                A[j+k]=A[j+k]+t;
            }
        }
    }
}
int ch[1000001];
int main(){
//	freopen("testdata.in","r",stdin); 
  //  freopen("out.txt","w",stdout);
	ll n,m;
    scanf("%lld",&n);
    m=n; 
    char c;
    For(i,0,n)	{
    	cin>>c; 
        a[i].x=c-'0';
    }
    For(i,0,m)	{
    	cin>>c;
        b[i].x=c-'0';
    }
    limit=1;
    while (limit<=m+n)	limit*=2,l++;
    For(i,0,limit)	r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    fast_fast_tle(a,1);
    fast_fast_tle(b,1);
    For(i,0,limit+1)	a[i]=a[i]*b[i];
    fast_fast_tle(a,-1);
    For(i,0,m+n-1)	ch[i+1]=(int)(a[i].x/limit+0.5);
	int ed=1;
	for (int i=m+n-1;i>=1;i--)
		if (ch[i]>=10){
			ch[i-1]+=ch[i]/10;
			ch[i]%=10;
			if (i==1)	ed=0;
		}
	while(ch[ed]==0&&ed<m+n-1)	ed++;
	For(i,ed,m+n)	printf("%d",ch[i]);	
    return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值