4.2米国のミッションペンの質問4(ハッシュ半分)

ここに画像を挿入説明

解像度:

まずハッシュ。(同一のサブストリングの分析)

そして、2つの位置を列挙する J I、J 、ABA始点Aの2人の代表は、iとjです。

最初の [ + K - 1 ] [I、I + K-1] 及び [ J J + K - 1 ] [J、J + K-1] と同じであることが、最大バイナリは、Lを発見しました [ + L - 1 ] [I、I + L-1] 及び [ J J + L - 1 ] [J、J + L-1]

この時間に 、開始します [ J + K - 1 J + L - 1 ] [J + K-1、J + L-1] 文字列のタイトル端面の要件を満たすことができます。
しかし、同じi、jは、とても同じ私のために、上記の異なる繰り返しを持っています [ J + K - 1 J + L - 1 ] [J + K-1、J + L-1] セグメント、ウェイトベクトルが詰めたソートなど。

コード:

/*
 *  Author : Jk_Chen
 *    Date : 2020-04-02-19.23.43
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+9;
const int maxn=1e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

char x[2009];
LL has[2009];
LL bas[2009];
LL getHash(int l,int r){
    return (has[r]-has[l-1]*bas[r-l+1]%mod+mod)%mod;
}

int main(){
    scanf("%s",x+1);
    int len=strlen(x+1);
    bas[0]=1;
    has[0]=0;
    rep(i,1,len){
        bas[i]=bas[i-1]*103%mod;
        has[i]=(has[i-1]*103+(x[i]-'a'))%mod;
    }
    int k;cin>>k;
    int sum=0;
    rep(i,1,len){
        vector<pill>V;
        rep(j,i+k+1,len){
            if(j+k-1>len)break;
            if(getHash(i,i+k-1)!=getHash(j,j+k-1))continue;
            int l=k,r=min(len-j+1,j-1-i),ans=k;
            while(l<=r){
                int mid=l+r>>1;
                if(getHash(i,i+mid-1)==getHash(j,j+mid-1))ans=mid,l=mid+1;
                else r=mid-1;
            }
            V.push_back({j+k-1,j+ans-1});
        }
        if(V.empty())continue;
        sort(V.begin(),V.end());
        int l=V[0].fi,r=V[0].se;

        for(auto P:V){
            if(P.fi>r+1){
                sum+=r-l+1;
                l=P.fi,r=P.se;
            }
            else{
                r=max(r,P.se);
            }
        }
        sum+=r-l+1;
    }
    printf("%d\n",sum);
    return 0;
}

/*_________________________________________________________end*/

773元記事公開 ウォンの賞賛345 ビューに20万+を

おすすめ

転載: blog.csdn.net/jk_chen_acmer/article/details/105279655