# [BZOJ3790]神奇项链

[BZOJ3790]神奇项链

abcdcba
abcdef

0
2
5

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;

#define maxn 100010
#define oo 2147483647

int f[maxn], mnv[maxn<<2];
void build(int L, int R, int o) {
if(L == R) mnv[o] = f[L] = oo;
else {
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
build(L, M, lc); build(M+1, R, rc);
mnv[o] = min(mnv[lc], mnv[rc]);
}
return ;
}
void update(int L, int R, int o, int p, int v) {
if(L == R) mnv[o] = f[L] = v;
else {
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
if(p <= M) update(L, M, lc, p, v);
else update(M+1, R, rc, p, v);
mnv[o] = min(mnv[lc], mnv[rc]);
}
return ;
}
int query(int L, int R, int o, int ql, int qr) {
if(ql <= L && R <= qr) return mnv[o];
int M = L + R >> 1, lc = o << 1, rc = lc | 1, ans = oo;
if(ql <= M) ans = min(ans, query(L, M, lc, ql, qr));
if(qr > M) ans = min(ans, query(M+1, R, rc, ql, qr));
return ans;
}

int Len[maxn];
char Str[maxn], S[maxn];

int main() {
while(scanf("%s", Str + 1) == 1) {
int n = strlen(Str + 1);
for(int i = 1; i <= n; i++) S[i<<1] = Str[i], S[(i<<1)-1] = '#';
n = n << 1 | 1; S[n] = '#';
//      S[n+1] = '\0'; printf("%s\n", S + 1);
int mxi = 0;
for(int i = 1; i <= n; i++) {
int mxp = mxi + Len[mxi] - 1;
if(mxp < i) Len[i] = 1;
else Len[i] = min(Len[(mxi<<1)-i], mxp - i + 1);
while(1 <= i - Len[i] + 1 && i + Len[i] - 1 <= n && S[i-Len[i]+1] == S[i+Len[i]-1])
Len[i]++;
Len[i]--;
if(mxp < i + Len[i] - 1) mxi = i;
}
build(0, n, 1);
update(0, n, 1, 0, -1);
for(int i = 1; i <= n; i++) {
int ql = i - Len[i], qr = n;
int tmp = query(0, n, 1, ql, qr) + 1;
if(tmp < f[i+Len[i]-1]) update(0, n, 1, i + Len[i] - 1, tmp);
}
printf("%d\n", f[n]);
}

return 0;
}


posted @ 2017-02-11 14:22  xjr01  阅读(314)  评论(0编辑  收藏  举报