夢のように見ているようです

https://loj.ac/problem/10047

タイトル説明

  文字列指定された\(S \)サブストリング満たすと判定され、\(ABA \)形式及び(| A |≧K \)\ \ (|≧1 \ | B)数。

考え

  この問題は、まず明確にされている\(N ^ 2 \)暴力治療することができるが、定義されたタイトルに変換することができる(\)\共通接頭辞と接尾辞を超える長さのサブストリングである\(K \)全体サブ未満長さ\(\ FRAC。1} {2} {\) 我々は考える(KMP \)\共通接頭辞と接尾辞を求め、その後、判断が暴力的なことができます。しかし、先にジャンプし続けることたびに、アカウントに裁判官を取って、残業の可能性がある、我々は、最適化を検討してください。まず、我々は明らかに列挙するために、各文字列の左端を列挙(NK * 2 \)\をそれに。次にため\(1- \シムN \)一度この期間\(KMP \) ため\(S [L ... R] \) このセクションでは、我々はプロセスを考える(P [I] = J \)\を、場合\(J <K-L 1 + \) 次いで最長共通接頭辞と接尾辞は、満たされていない(=私は\ G [I])\、すなわちのみこの期間全体\(A \)文字列、そうでない場合に関連して、条件を満たし(G [J] \)\条件を、我々はそれ以降の状態にできるだけ短いので、ほとんど影響したいので。中間位置のかどうか、この項の判断の答え限り、最後に記録された位置。

コード

#include <bits/stdc++.h>
using namespace std;
const int MAXN=2e4+10;
char s[MAXN];
int pre[MAXN],n,g[MAXN];
int main() 
{
    int k;
    scanf(" %s",s+1);
    scanf("%d",&k);
    n=strlen(s+1);
    int ans=0;
    for(int l=1;l<=n-(k<<1);l++)
    {
        pre[l]=l-1;
        int j=l-1;
        g[l]=l;
        for(int p=l;p<n;p++)
        {
            while(j>l-1&&s[p+1]!=s[j+1])j=pre[j];
            if(s[p+1]==s[j+1])j++;
            pre[p+1]=j;
            g[p+1]=(j<l+k-1)?p+1:g[j];
            if(g[p+1]<(l+p+1)/2)
                ans++;
        }
    }
    printf("%d",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/fangbozhen/p/11788215.html