字符串hash+找模数——cf985F

19260817比自然溢出都要好使

/*
把原串变成用26个01串表示,第i个串对应的字符是i
然后进行字符串hash,s和t双射的条件是26个串的hash值排序后一一相等 
*/
#include<bits/stdc++.h>
using namespace std;
#define ll unsigned long long

const ll p = 13331; 
const int maxn = 200005;
const ll mod = 19260817;

char s[maxn];
int n,m;
ll ash[maxn][26];
void init(){
    for(int i=0;i<26;i++)
        for(int j=1;j<=n;j++){
            int cur;
            if(s[j]-'a'==i)cur=1;
            else cur=0;
            if(j>0)ash[j][i]=(ash[j-1][i]*p%mod+cur)%mod;
            else ash[j][i]=cur;
        }
}

ll F[maxn];

int calc(int x,int y,int len){
    ll a[26]={},b[26]={};
    for(int i=0;i<26;i++){
        a[i]=(ash[x+len-1][i]-ash[x-1][i]*F[len]%mod+mod)%mod;
        b[i]=(ash[y+len-1][i]-ash[y-1][i]*F[len]%mod+mod)%mod;
    }
    sort(a,a+26);sort(b,b+26);
    for(int i=0;i<26;i++)
        if(a[i]!=b[i])return 0;
    return 1;
}


int main(){
    F[0]=1;
    for(int i=1;i<maxn;i++)
        F[i]=F[i-1]*p%mod;
    cin>>n>>m;
    cin>>s+1;
    init();
    while(m--){
        int x,y,len;
        cin>>x>>y>>len;x,y;
        if(calc(x,y,len))puts("YES");
        else puts("NO");
    }
} 
原文地址:https://www.cnblogs.com/zsben991126/p/11170486.html