50PT求调
查看原帖
50PT求调
456675
a_sad_soul楼主2025/1/16 22:22
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3e6+10;
int pre[MAXN];
int len[MAXN];
int nxt[MAXN];
char s1[MAXN],s2[MAXN];
typedef unsigned long long ull;
typedef long long ll;
ll hf[MAXN],hb[MAXN];
ll P[MAXN];
const ll M=1313;
const ll MOD = (1ll<<32);
int n,m;
ll Hash_F(int l,int r){
   return (hf[r]-hf[l-1]*P[r-l+1]%MOD+MOD)%MOD; 
}
ll Hash_B(int l,int r){
    return (hb[l]-hb[r+1]*P[r-l+1]%MOD+MOD)%MOD;
}
int solve(int i){
    int ans=0,l=1,r=min(i-1,n-i),mid;
    while(l<=r){
        mid=(l+r)>>1;
        if(Hash_F(i+1,i+mid)==Hash_B(i-mid,i-1))ans=mid,l=mid+1;
        else r=mid-1;
    }
    return ans;
}
ll ss[MAXN],sss[MAXN];
void Init(){
    P[0]=1;
    for(int i=1;i<=n;++i)P[i]=P[i-1]*M%MOD;
    for(int i=1;i<=n;++i)hf[i]=(hf[i-1]*M%MOD+s1[i])%MOD;
    for(int i=n;i;--i)hb[i]=(hb[i+1]*M%MOD+s1[i])%MOD;
    int j=0;
    for(int i=2;i<=m;++i){
        while(j&&s2[j+1]!=s2[i])j=nxt[j];
        if(s2[j+1]==s2[i])++j;
        nxt[i]=j;
    }
    j=0;
    for(int i=1;i<=n;++i){
        while(j&&s2[j+1]!=s1[i])j=nxt[j];
        if(s2[j+1]==s1[i])++j;
        if(j==m)pre[i]=1,j=nxt[j];
    }
    for(int i=1;i<=n;++i){
        ss[i]=(ss[i-1]+pre[i]*i%MOD)%MOD;
        sss[i]=(sss[i-1]+pre[i]*(n-i+1)%MOD)%MOD;
        pre[i]+=pre[i-1];
    }
}
ll calc(int l,int r){
    if(r<l)return 0;
    int mid=(l+r)>>1;
    ll L=((ss[mid]-ss[l-1]+MOD)%MOD-(pre[mid]-pre[l-1])*(l-1)%MOD+MOD)%MOD;
    ll R=((sss[r]-sss[mid]+MOD)%MOD-(pre[r]-pre[mid])*(n-r)%MOD)%MOD;
    return (L+R)%MOD;
}
int main(){
    scanf("%d%d",&n,&m);
    scanf("%s",s1+1);
    scanf("%s",s2+1);
    Init();
    ll ans=0;
    for(int i=1;i<=n;++i){
        int len=solve(i);
           ans+=calc(i-len+m-1,i+len);
    }
    printf("%lld\n",ans);
    return 0;
}

不会哈希碰撞了吧

2025/1/16 22:22
加载中...