zoukankan      html  css  js  c++  java
  • 【刷题】BZOJ 2179 FFT快速傅立叶

    Description

    给出两个n位10进制整数x和y,你需要计算x*y。

    Input

    第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。

    Output

    输出一行,即x*y的结果。

    Sample Input

    1
    3
    4

    Sample Output

    12

    数据范围:
    n<=60000

    Solution

    水体一道
    把一个数变化一下, (overline {xyz}=x*10^2+y*10^1+z*10^0) ,就是一个多项式形式了
    两个数相乘,多项式相乘,FFT
    然后处理进位就好了

    #include<bits/stdc++.h>
    #define ui unsigned int
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    const int MAXN=1<<19;
    const db Pi=acos(-1.0);
    int n,m,qn,rev[MAXN],cnt,ans[MAXN];
    char s1[MAXN],s2[MAXN];
    struct Complex{
    	db real,imag;
    	inline Complex operator + (const Complex &A) const {
    		return (Complex){real+A.real,imag+A.imag};
    	};
    	inline Complex operator - (const Complex &A) const {
    		return (Complex){real-A.real,imag-A.imag};
    	};
    	inline Complex operator * (const Complex &A) const {
    		return (Complex){real*A.real-imag*A.imag,imag*A.real+real*A.imag};
    	};
    };
    Complex x[MAXN],y[MAXN];
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char ch='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(ch!='')putchar(ch);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    inline void FFT(Complex *A,int tp)
    {
    	for(register int i=0;i<n;++i)
    		if(i<rev[i])std::swap(A[i],A[rev[i]]);
    	for(register int l=2;l<=n;l<<=1)
    	{
    		Complex wn=(Complex){cos(2*Pi/l),sin(tp*2*Pi/l)};
    		for(register int i=0;i<n;i+=l)
    		{
    			Complex w=(Complex){1,0};
    			for(register int j=0;j<(l>>1);++j)
    			{
    				Complex A1=A[i+j],A2=w*A[i+j+(l>>1)];
    				A[i+j]=A1+A2,A[i+j+(l>>1)]=A1-A2;
    				w=w*wn;
    			}
    		}
    	}
    }
    int main()
    {
    	read(qn);
    	scanf("%s",s1);scanf("%s",s2);
    	for(register int i=0;i<qn;++i)x[qn-i-1].real=s1[i]-'0';
    	for(register int i=0;i<qn;++i)y[qn-i-1].real=s2[i]-'0';
    	m=qn+qn-1;
    	for(n=1;n<m;n<<=1)cnt++;
    	for(register int i=0;i<n;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(cnt-1));
    	FFT(x,1);FFT(y,1);
    	for(register int i=0;i<n;++i)x[i]=x[i]*y[i];
    	FFT(x,-1);
    	int ps=0;
    	for(register int i=m-1;i>=0;--i)
    		if((int)(x[i].real/n+0.5)!=0)
    		{
    			ps=i;
    			break;
    		}
    	for(register int i=ps;i>=0;--i)ans[i]=(int)(x[i].real/n+0.5);
    	for(register int i=0;i<ps;++i)ans[i+1]+=ans[i]/10,ans[i]%=10;
    	for(register int i=ps;i>=0;--i)write(ans[i]);
    	puts("");
    	return 0;
    }
    
  • 相关阅读:
    石头的用途
    [转] Analysis: Khronos and OpenGL ARB merge
    ★○值得你我珍藏一世的80句话○★
    PasswordStrength 控件
    NumericUpDownExtender 控件
    ReorderList控件
    Nobot控件拒绝机器人行为
    PopupControlExtender控件
    PagingBulletedList 控件学习
    MutuallyExlcusiveCheckBox控件
  • 原文地址:https://www.cnblogs.com/hongyj/p/9194455.html
Copyright © 2011-2022 走看看