hdu4763 扩展kmp

来源:互联网 发布:淘宝潮牌男模特排名 编辑:程序博客网 时间:2024/06/10 01:28

题意是在一个字符串中找出一个前缀一个后缀和一个中间的子串,互相不重叠并且三部分完全一样

运用的是exKMP

对自身求一个next数组

next[i]表示以i为开始位置的子串与整个串的前缀最长匹配到多少长度


然后就是枚举了

注意到我们枚举后三分一的位置时,如果某个位置为i,

且next[i]+ i == len。

也就是子串的长度为next[i]了

//  Created by Chenhongwei in 2015.//  Copyright (c) 2015 Chenhongwei. All rights reserved.#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <climits>#include <queue>#include <cmath>#include <map>#include <set>#include <stack>#include <vector>#include <sstream>#include <algorithm>#include <ctime>using namespace std;const int inf=1e9;const int maxn=1e6+100;typedef long long ll;typedef unsigned long long ull;char t[maxn];int nxt[maxn];void pre_exkmp(char *t){int n=strlen(t);nxt[0]=n;int j=0;while(j+1<n&&t[j+1]==t[j]) j++;nxt[1]=j;int a=1,p,l;for(int i=2;i<n;i++){p=a+nxt[a]-1;l=nxt[i-a];if(i+l<p+1)nxt[i]=l;else{j=max(0,p-i+1);while(i+j<n&&t[i+j]==t[j])j++;nxt[i]=j;a=i;}}}int main(){//ios::sync_with_stdio(false);// freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);int T;scanf("%d",&T);while(T--){scanf("%s",t);int len=strlen(t);pre_exkmp(t);int ans=0,mlen;for(int i=2*len/3;i<len;i++){if(i+nxt[i]!=len)continue;ans=nxt[i];break;}printf("%d\n",ans);}return 0;}


0 0
原创粉丝点击