MnZn 求助 NTT
查看原帖
MnZn 求助 NTT
420129
Nt_Tsumiki楼主2024/6/29 21:54

跑的巨慢,有没有佬帮忙看看哪里写假了。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>

#define N 400001
#define MOD 998244353
#define LL long long

using namespace std;
int T,len0,len,to[N];
LL inv,f[N],g[N],res[N];
string s0,s;
const char ch[]={'A','T','G','C'};

LL quickpow(LL a,int k) {
    LL res=1;
    while (k) {
        if (k&1) res=res*a%MOD;
        a=a*a%MOD,k>>=1;
    }
    return res;
}

void NTT(LL *A,int n,int op) {
    for (int i=0;i<n;i++)
        if (i<to[i]) swap(A[i],A[to[i]]);
    for (int i=1;i<n;i<<=1) {
        LL wk=quickpow(op==1?3:inv,(MOD-1)/(i<<1));
        for (int j=0;j<n;j+=(i<<1))
            for (LL k=j,w1=1;k<i+j;k++,w1=w1*wk%MOD) {
                LL pe=A[k],po=w1*A[i+k]%MOD;
                A[k]=(pe+po)%MOD,A[i+k]=(pe-po+MOD)%MOD;
            }
    }
}

int main() {
    scanf("%d",&T); inv=quickpow(3,MOD-2);
    while (T--) {
        cin>>s0>>s; len0=s0.size(),len=s.size();
        int n=1,m=len+len0,k=0;
        while (n<=m) n<<=1,k++;
        memset(to,0,sizeof to);
        memset(res,0,sizeof res);
        for (int j=0;j<n;j++) to[j]=(to[j>>1]>>1)|((j&1)<<(k-1));
        for (int i=0;i<4;i++) {
            for (int j=0;j<n;j++) f[j]=g[j]=0;
            for (int j=0;j<len0;j++) f[j]=(s0[j]==ch[i]);
            for (int j=0;j<len;j++) g[len-j-1]=(s[j]==ch[i]);
            NTT(f,n,1),NTT(g,n,1);
            for (int j=0;j<n;j++) f[j]=f[j]*g[j]%MOD;
            NTT(f,n,0);
            for (int j=0;j<len0;j++) res[j]=(res[j]+(f[j]*quickpow(n,MOD-2)%MOD));
        }
        int ans=0;
        for (int i=len-1;i<len0;i++)
            if (res[i]+3>=len) ans++;
        printf("%d\n",ans);
    }
    return 0;
}
2024/6/29 21:54
加载中...