5 xy abc aaa aaaaba aaxoaaaaa
0 0 1 1 2
题意其实就是要找到这个字符串的某个前缀, 它在串中至少出现了三次(末尾1次,中间一次, 开头一次)
那么我们可以用EKMP,先把next数组预处理出来(串和串本身的每一个后缀的最长公共前缀), 然后用树状数组维护大于等于next[i]的值的个数
显然符合的次数肯定大于等于3, 然后只要从后往前去找那些 i + next[i] == len 的 后缀(只有匹配到结束才说明存在某个前缀出现在后缀里),找一个最大值就行
复杂度O(nlogn)
/*************************************************************************
> File Name: hdu4763.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年02月02日 星期一 13时11分11秒
************************************************************************/
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;
const int N = 1000100;
char T[N];
int next[N];
int cnt_hash[N];
int tree[N];
int lowbit (int x)
{
return x & (-x);
}
void add (int x)
{
for (int i = x; i <= N; i += lowbit(i))
{
++tree[i];
}
}
int sum (int x)
{
int ans = 0;
for (int i = x; i; i -= lowbit (i))
{
ans += tree[i];
}
return ans;
}
void EKMP ()
{
int lent = strlen (T);
next[0] = lent;
int i, j, p, L;
j = 0;
while (j + 1 < lent && T[j] == T[j + 1])
{
++j;
}
next[1] = j;
int a = 1;
for (int i = 2; i < lent; ++i)
{
p = next[a] + a - 1;
L = next[i - a];
if (i + L < p + 1)
{
next[i] = L;
}
else
{
j = max (0, p - i + 1);
while (i + j < lent && T[i + j] == T[j])
{
++j;
}
next[i] = j;
a = i;
}
}
}
int main ()
{
int t;
scanf("%d", &t);
while (t--)
{
memset (next, 0, sizeof(next));
memset (tree, 0, sizeof(tree));
scanf("%s", T);
EKMP ();
int len = strlen (T);
int maxs = 0;
int zero = 0;
for (int i = 0; i < len; ++i)
{
if (next[i] == 0)
{
++zero;
continue;
}
add (next[i]);
}
for (int i = len - 1; i >= 0; --i)
{
if (next[i] == 0)
{
continue;
}
if (i + next[i] - 1 != len - 1)
{
continue;
}
int cnt = len - sum (next[i] - 1) - zero;
if (cnt >= 3)
{
maxs = max (maxs, next[i]);
}
}
printf("%d\n", maxs);
}
return 0;
}原文地址:http://blog.csdn.net/guard_mine/article/details/43407295