您的位置:首页 > 其它

BZOJ 2803: [Poi2012]Prefixuffix

2017-07-01 19:46 323 查看

Description

对于两个串S1、S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同。例如串ababba和串abbaab是循环相同的。

给出一个长度为n的串S,求满足下面条件的最大的L:

1. L<=n/2

2. S的L前缀和S的L后缀是循环相同的。

Input

第一行一个正整数n (n<=1,000,000)。第二行n个小写英文字母,表示串S。

Output

一个整数,表示最大的L。

Sample Input

15

ababbabababbaab

Sample Output

6

HINT

Source

结论题

循环同构可以分解为[1...i][i + 1...j]...[n - j + 1, n - i][n - i + 1...n]

然后s[1...i] = s[n - i + 1...n], s[i + 1...j] = s[n - j + 1, n - i]

中间那个是一个border,如果记f[i]表示s[i...n - i + 1]的border,那么f[i - 1] <= f[i] + 2

证明的话, 用f[i - 1]很容易构造出一个f[i - 1] - 2的f[i]

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill(x, y) memset(x, y, sizeof x)
#define copy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef unsigned long long LL;
typedef pair < int, int > pa;

inline int read()
{
int sc = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') sc = sc * 10 + ch - '0', ch = getchar();
return sc * f;
}

const int MAXN = 1000005;
const int bas1 = 2333;
const int bas2 = 2551;
const int mod1 = 1e9 + 7;
const int mod2 = 1e9 + 9;

int n, ans;
char s[MAXN];

struct Hsh
{
int f[MAXN], g[MAXN], p[MAXN], q[MAXN];

inline void init()
{
p[0] = q[0] = 1;
for (int i = 1; i <= n; i ++)
p[i] = 1LL * p[i - 1] * bas1 % mod1, q[i] = 1LL * q[i - 1] * bas2 % mod2;
for (int i = 1; i <= n; i ++)
f[i] = (1LL * f[i - 1] * bas1 + s[i]) % mod1, g[i] = (1LL * g[i - 1] * bas2 + s[i]) % mod2;
}

inline pa get(int l, int r)
{
return mp((f[r] - 1LL * f[l - 1] * p[r - l + 1] % mod1 + mod1) % mod1, (g[r] - 1LL * g[l - 1] * q[r - l + 1] % mod2 + mod2) % mod2);
}
}h;

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
n = read();
scanf("%s", s + 1);
h.init();
for (int i = n >> 1, j = 0; ~i; i --, j = min((n >> 1) - i, j + 2))
if (h.get(1, i) == h.get(n - i + 1, n))
for (; ~j; j --)
if (h.get(i + 1, i + j) == h.get(n - i - j + 1, n - i))
{
ans = max(ans, i + j);
break;
}
return printf("%d\n", ans), 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: