1. 程式人生 > >【BZOJ 3790】 神奇項鏈

【BZOJ 3790】 神奇項鏈

clu UC IV std using har www oid code

【題目鏈接】

https://www.lydsy.com/JudgeOnline/problem.php?id=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; }

【BZOJ 3790】 神奇項鏈