TLE 60pts求助
查看原帖
TLE 60pts求助
782481
wuyue__X楼主2025/1/3 20:49

哈希 TLE 60pts 如何优化

(虽然我知道用unsigned long long就能AC了)

#include<bits/stdc++.h>
#define int long long 
using namespace std;
int mod=998244353,b=10029;
int n,m,a[109999],h[199999],h2[199999],p[199999];
char s1[109999],s2[109999];
int l1,l2;
int hsh(int l,int r){
    return ((h[r]+mod-h[l-1]*p[r-l+1]%mod)%mod);
}
int hsh2(int l,int r){
    return ((h2[r]+mod-h2[l-1]*p[r-l+1]%mod)%mod);
}
int binary_search(int x){
    int x2=x+l2-1,y=0,l=1,r=l2;
	for(int i=1;i<=3;i++){

        l=1;
        r=l2-y+1;
        int ans=0;
        while(l<=r){
            int mid=(l+r)>>1;
            
            if(hsh(x,x+mid-1)==hsh2(y,y+mid-1)){
                ans=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        //cout<<ans<<endl;


        y=y+ans+1;
        x=x+ans+1;
        
        if(y>l2-1) return 1;
        
	}
    //cout<<x<<"   "<<x2<<"  " <<y<<" "<<l2-1;
	return hsh(x,x2)==hsh2(y,l2-1);

}
signed main(){
    
    int t,cnt=0;
    scanf("%lld",&t);
    p[0]=1;
    for(int i=1;i<100999;i++){
        p[i]=(p[i-1]*b)%mod;
    }
    while(t--){
        cnt=0;
        // memset(h,0,sizeof(h));
        // memset(h2,0,sizeof(h2));
        scanf("%s%s",s1,s2);
        l1=strlen(s1),l2=strlen(s2);
        if(l1<l2){printf("0\n");continue;}
        for(int j=0;j<l1;j++){
            h[j]=(h[j-1]*b%mod+s1[j])%mod;
        }
        for(int j=0;j<l2;j++){
            h2[j]=(h2[j-1]*b%mod+s2[j])%mod;
        }

        
        for(int i=0;i<l1-l2+1;i++){
            if(binary_search(i)){
                cnt++;
            }
        }
        printf("%lld\n",cnt);

        
    }





    return 0;
}
2025/1/3 20:49
加载中...