FFT(NTT)学习笔记

慢慢更?
咕咕日报
FFT板子-1
AC代码


#include<bits/stdc++.h>
using namespace std;
int n1,n2,P=1,n,jw,tot,res[1000010];
char ip1[100010],ip2[100010];
double Pi=3.14159265;
struct comp
{
    comp (double xx=0,double yy=0)
    {
        x=xx,y=yy;
    }
    double x,y;
};
comp operator + (comp a,comp b)
{
    return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b)
{
    return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b)
{
    return comp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
comp a[500010],b[500010],tmp[500010];
int FFT(comp *s,int now,int len,int pd)
{
    if(!len)
        return 0;
    for(int i=now;i<now+len*2;i++)
        tmp[i]=s[i];
    for (int i=now;i<now+len;i++)
    {
        s[i]=tmp[now+((i-now)*2)];
        s[i+len]=tmp[now+(((i-now)*2)|1)];
    }
    FFT(s,now,len/2,pd);
    FFT(s,now+len,len/2,pd);
    comp dwg,nowdwg;
    dwg=comp(cos(Pi/len),sin(Pi/len)*pd);
    nowdwg.x=1;
    nowdwg.y=0;
    for(int i=now;i<now+len;i++)
    {
    	comp tt=nowdwg*s[i+len];
    	tmp[i]=s[i]+tt;
    	tmp[i+len]=s[i]-tt;
    	nowdwg=nowdwg*dwg;
    }
    for(int i=now;i<now+len*2;i++)
        s[i]=tmp[i];
}
int TS(double x)
{
	if(x-floor(x)>=0.5)
	{
		return ceil(x);
	}
	else
	{
		return floor(x);
	}
}
int main()
{
    scanf("%d",&n);
    n--;
	n1=n;n2=n;
	cin>>ip1;	 
    for(int i=0;i<=n1;i++)
    {
        a[i].x=ip1[i]-48;
    }
    cin>>ip2; 
    for(int i=0;i<=n2;i++)
    {
        b[i].x=ip2[i]-48;
    }
    for(;P<=n1+n2;P*=2)
    {
        
    }
    FFT(a,0,P/2,1);
    FFT(b,0,P/2,1);
    for(int i=0;i<P;i++)
        a[i]=a[i]*b[i];
    FFT(a,0,P/2,-1);
    /*for(int i=0;i<=n1+n2;i++)
        printf("%.0lf ",fabs(a[i].x)/P);*/
   	for(int i=n1+n2;i>=0;i--)
   	{
		res[tot++]=TS(fabs(a[i].x)/P);
   	}
   	for(int i=0;i<=P;i++)
   	{
   		res[i+1]+=res[i]/10;
   		res[i]%=10;
   	}
   	while(!res[P])
   	{
   		P--;
   	}
	for(int i=P;i>=0;i--)
	{
		printf("%d",res[i]);
	}
} 

FFT板子-2
AC代码


#include<bits/stdc++.h>
using namespace std;
int n1,n2,P=1;
double Pi=3.14159265;
struct comp
{
    comp (double xx=0,double yy=0)
    {
        x=xx,y=yy;
    }
    double x,y;
};
comp operator + (comp a,comp b)
{
    return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b)
{
    return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b)
{
    return comp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
comp a[500010],b[500010],tmp[500010];
int FFT(comp *s,int now,int len,int pd)
{
    if(!len)
        return 0;
    for(int i=now;i<now+len*2;i++)
        tmp[i]=s[i];
    for (int i=now;i<now+len;i++)
    {
        s[i]=tmp[now+((i-now)*2)];
        s[i+len]=tmp[now+(((i-now)*2)|1)];
    }
    FFT(s,now,len/2,pd);
    FFT(s,now+len,len/2,pd);
    comp dwg,nowdwg;
    dwg=comp(cos(Pi/len),sin(Pi/len)*pd);
    nowdwg.x=1;
    nowdwg.y=0;
    for(int i=now;i<now+len;i++)
    {
    	comp tt=nowdwg*s[i+len];
    	tmp[i]=s[i]+tt;
    	tmp[i+len]=s[i]-tt;
    	nowdwg=nowdwg*dwg;
    }
    for(int i=now;i<now+len*2;i++)
        s[i]=tmp[i];
}
int main()
{
    scanf("%d%d",&n1,&n2);
    for(int i=0;i<=n1;i++)
    {
        scanf("%lf",&a[i].x);
    }
    for(int i=0;i<=n2;i++)
    {
        scanf("%lf",&b[i].x);
    }
    for(;P<=n1+n2;P*=2)
    {
        
    }
    FFT(a,0,P/2,1);
    FFT(b,0,P/2,1);
    for(int i=0;i<P;i++)
        a[i]=a[i]*b[i];
    FFT(a,0,P/2,-1);
    for(int i=0;i<=n1+n2;i++)
        printf("%.0lf ",fabs(a[i].x)/P);
} 

然后是蝴蝶变换版(更好打?)

#include<bits/stdc++.h>
using namespace std;
int n1,n2,P=1,r[2000010];
double Pi=3.14159265;
struct comp
{
    comp (double xx=0,double yy=0)
    {
        x=xx,y=yy;
    }
    double x,y;
};
comp operator + (comp a,comp b)
{
    return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b)
{
    return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b)
{
    return comp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
comp a[500010],b[500010],tmp[500010];
int FFT(comp *s,int pd)
{   
    for(int i=0;i<P;i++)
    {
    	if(i<r[i])
		{
     		comp tmpp=s[i];
    		s[i]=s[r[i]];
     		s[r[i]]=tmpp;
   		}
    }
    for(int len=2;len<=P;len*=2)
    {
    	int Len=len/2;
    	comp dwg(cos(Pi/Len),pd*sin(Pi/Len));
    	for(int k=0;k<P;k+=len)
		{
      		comp qwq(1,0);
      		for(int l=k;l<k+Len;l++)
			{
        		comp tt=qwq*s[Len+l];
        		s[Len+l]=s[l]-tt;
        		s[l]=s[l]+tt;
       			qwq=qwq*dwg;
      		}
    	}	
    }
}
int main()
{
    scanf("%d%d",&n1,&n2);
    for(int i=0;i<=n1;i++)
    {
        scanf("%lf",&a[i].x);
    }
    for(int i=0;i<=n2;i++)
    {
        scanf("%lf",&b[i].x);
    }
    for(;P<=n1+n2;P*=2)
    {
        
    }
    for(int i=0;i<P;i++)
		r[i]=(r[i/2]/2)+((i%2)?P>>1:0);
	FFT(a,1);
	FFT(b,1);
	for(int i=0;i<P;i++)
	{
		a[i]=a[i]*b[i];
	}
	FFT(a,-1);
	for(int i=0;i<=n1+n2;i++)
		printf("%.0f ",fabs(a[i].x)/P);
} 

NTT?
咕咕咕

posted @ 2019-02-15 19:53  G_A_TS  阅读(481)  评论(0编辑  收藏  举报