# 【BZOJ 3790】 神奇项链

【题目链接】

【算法】

manacher + 贪心

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXN 500010

char s[MAXN];

struct info
{
int l,r;
};
inline bool cmp(info a,info b)
{
return a.l != b.l ? a.l < b.l : a.r > b.r;
}
inline void Manacher()
{
int i,len,pos = 0,mx = 0,n = 0,ans,r;
static int p[MAXN<<1];
static char tmp[MAXN<<1];
static info a[MAXN<<1];
len = strlen(s+1);
for (i = 1; i <= len; i++)
{
tmp[2*i-1] = '#';
tmp[2*i] = s[i];
}
tmp[len = 2 * len + 1] = '#';
for (i = 1; i <= len; i++)
{
if (mx > i) p[i] = min(p[2*pos-i],mx-i);
else p[i] = 1;
while (i - p[i] >= 1 && i + p[i] <= len && tmp[i-p[i]] == tmp[i+p[i]]) p[i]++;
if (i + p[i] - 1 > mx)
{
mx = i + p[i] - 1;
pos = i;
}
}
for (i = 1; i <= len; i++) a[++n] = (info){i-p[i]+1,i+p[i]-1};
sort(a+1,a+n+1,cmp);
r = a[1].r; ans = 1; pos = 2;
while (r < len)
{
mx = r;
while (pos <= n && a[pos].l <= r + 1)
{
mx = max(mx,a[pos].r);
pos++;
}
ans++;
r = mx;
}
printf("%d\n",ans-1);
}

int main()
{

while (scanf("%s",s+1) != EOF) Manacher();

return 0;

}

posted @ 2018-07-01 12:02  evenbao  阅读(106)  评论(0编辑  收藏  举报