• 【洛谷P1919】【模板】A*B Problem升级版


    题目

    题目链接:https://www.luogu.com.cn/problem/P1919
    给出两个数 \(a,b\),求 \(a\times b\)

    思路

    类比列竖式的时候,从低位往高位数,分别为 \(i,j\) 两位的数字相乘会到第 \(i+j-1\) 位。
    这其实就是一个卷积的形式,直接上 FFT 即可。
    注意需要在跑完 FFT 之后进位。
    时间复杂度 \(O(n\log n)\)

    代码

    #include <bits/stdc++.h>
    #define cp complex<double>
    using namespace std;
    
    const int N=3000010;
    const double pi=acos(-1);
    int n,m,Maxn=1,rev[N],h[N];
    char ch[N];
    cp f[N],g[N];
    
    void fft(cp *f,int tag)
    {
    	for (int i=0;i<Maxn;i++)
    		if (i<rev[i]) swap(f[i],f[rev[i]]);
    	for (int mid=1;mid<Maxn;mid<<=1)
    	{
    		cp temp(cos(pi/mid),tag*sin(pi/mid));
    		for (int i=0;i<Maxn;i+=(mid<<1))
    		{
    			cp w(1,0);
    			for (int j=0;j<mid;j++,w*=temp)
    			{
    				cp x=f[i+j],y=w*f[i+j+mid];
    				f[i+j]=x+y; f[i+j+mid]=x-y;
    			}
    		}
    	}
    }
    
    int main()
    {
    	scanf("%s",ch); n=strlen(ch);
    	for (int i=0;i<n;i++) f[i]=cp(1.0*(ch[n-i-1]-48),0.0);
    	scanf("%s",ch); m=strlen(ch);
    	for (int i=0;i<m;i++) g[i]=cp(1.0*(ch[m-i-1]-48),0.0);
    	n+=m;
    	while (Maxn<=n) Maxn<<=1;
    	for (int i=0;i<Maxn;i++)
    		rev[i]=(rev[i>>1]>>1)|((i&1)?(Maxn>>1):0);
    	fft(f,1); fft(g,1);
    	for (int i=0;i<Maxn;i++) f[i]*=g[i];
    	fft(f,-1);
    	for (int i=0;i<=Maxn;i++)
    	{
    		h[i]+=(int)(f[i].real()/Maxn+0.4999);
    		if (i==Maxn && h[i]>9) Maxn++;
    		h[i+1]=h[i]/10; h[i]%=10;
    	}
    	int i=Maxn;
    	while (!h[i] && i) i--;
    	for (;i>=0;i--) printf("%d",h[i]);
    	return 0;
    }
    
  • 相关阅读:
    #Leetcode# 164. Maximum Gap
    #Leetcode# 155. Min Stack
    #Leetcode# 165. Compare Version Numbers
    Linux——信息分析(四)域名分析dig、host、
    Linux——信息采集(三)dmitry、路由跟踪命令tracerouter
    密码学——cookie攻击
    final关键字
    重载与重写
    break and continue
    计算机硬件系统
  • 原文地址:https://www.cnblogs.com/stoorz/p/13674624.html
Copyright © 2020-2023  润新知