萌新刚学OI,求助关于fft的卡常
查看原帖
萌新刚学OI,求助关于fft的卡常
154222
retaliatorElite楼主2021/12/31 23:29

rt, 最后两个点T了,其他都没问题,请问下各位大佬fft有什么卡常的经验/建议吗。。。然后这份代码有什么卡常的修改建议吗。。。

#include<bits/stdc++.h>
using namespace std;
long long read(){
    long long ret=0,neg=1;
    char ch;
    ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-'){
        neg=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        ret=(ret<<1)+(ret<<3)+(ch^48);
        ch=getchar();
    }
    return ret*neg;
}
void write(long long x){
    if(x<0) putchar('-'),x=-x;
    if(x>=10) write(x/10);
    putchar('0'+x%10);
}
const long double Pi=acos(-1);
struct compleX{
    long double r,i;
    compleX(long double x=0,long double y=0){r=x,i=y;}
};
compleX operator + (compleX x,compleX y){
    return compleX(x.r+y.r,x.i+y.i);
}
compleX operator - (compleX x,compleX y){
    return compleX(x.r-y.r,x.i-y.i);
}
compleX operator * (compleX x,compleX y){
    return compleX(x.r*y.r-x.i*y.i,x.r*y.i+x.i*y.r);
}
void bit_rev(compleX a[],int len){
    for(int i=0;i<len;i++){
        int tmp,tar=0;
        tmp=i;
        int ttt=1;
        while(ttt<len){
        	ttt*=2;
            tar<<=1;
            if(tmp&1) tar|=1;
            tmp>>=1;
        }
        if(tar>=i) swap(a[i],a[tar]);
    }
}
void dft(compleX a[],int len,int inv){
    bit_rev(a,len);
    for(int i=2;i<=len;i<<=1){
        compleX wn;
        wn=compleX(cos(Pi*2.0/i),(long double)inv*sin(Pi*2.0/i));
        for(int s=0;s<len;s+=i){
            compleX w;
            w=compleX(1,0);
            for(int k=0;k<i/2;k++){
                compleX tx,ty;
                tx=a[s+k];
                ty=a[s+k+i/2];
                a[s+k]=tx+(w*ty);
                a[s+k+i/2]=tx-(w*ty);
                w=w*wn;
            }
        }
    }
    if(inv==-1){
        for(int i=0;i<len;i++){
            a[i].r=a[i].r/(long double)len;
        }
    }
}
compleX a[4100000],b[4100000],res[4100000];
void fft(long double f[],long double g[],int l1,int l2){
    int len;
    len=0;
    while((1<<len)<=l1+l2) len++;
    len=(1<<len);
    for(int i=0;i<=l1;i++)
        a[i]=compleX(f[i],0);
    for(int i=l1+1;i<len;i++)
        a[i]=compleX(0,0);
    for(int i=0;i<=l2;i++)
        b[i]=compleX(g[i],0);
    for(int i=l2+1;i<len;i++)
        b[i]=compleX(0,0);
    dft(a,len,1);
    //cout<<"\nQAQ--------------\n";
    dft(b,len,1);
    for(int i=0;i<len;i++){
    	//cout<<i<<' '<<a[i].r<<' '<<a[i].i<<" | "<<b[i].r<<' '<<b[i].i<<endl;
    	//cout.flush();
        res[i]=a[i]*b[i];
    }
    dft(res,len,-1);
}
int n,m;
long double ta[4100000],tb[4100000];
int main(){
	//freopen("fft.in","r",stdin);
	//freopen("fft_tle.out","w",stdout);
    n=read();
    m=read();
    for(int i=0;i<=n;i++){
        ta[i]=read();
    }
    for(int i=0;i<=m;i++){
        tb[i]=read();
    }
    fft(ta,tb,n,m);
    for(int i=0;i<=n+m;i++){
        write(int(res[i].r+0.5));
        putchar(' ');
    }
	return 0;
}
2021/12/31 23:29
加载中...