回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。
输入一个字符串Str,输出Str里最长回文子串的长度。
Input输入Str(Str的长度 <= 100000)Output输出最长回文子串的长度L。Sample Input
daabaac
Sample Output
5
一个标准的Manacher,可以看看这篇博客,讲的很清楚:我就是“博客”。另外突然发现max,min好慢啊,而且其中的两种情况可以合并。附代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e5 + 5;
int RL[maxn << 1], cnt, mx;
char s[maxn << 1], r[maxn];
void Manacher() {
int Mr = 0, Mpos = 0;
int len = cnt;
for(register int i = 0; i < len; ++i) {
RL[i] = min(RL[(Mpos << 1) - i], Mr - i);
for(; i - RL[i] >= 0 && i + RL[i] <= len && s[i - RL[i]] == s[i + RL[i]]; ++RL[i]);
--RL[i];
if(Mr < RL[i] + i) Mr = i + RL[i], Mpos = i;
mx = max(mx, RL[i]);
}
}
int main() {
scanf("%s", r);
int mxr = strlen(r);
for(register int i = 0; i < mxr; ++i)
{s[cnt++] = '#', s[cnt++] = r[i];}
s[cnt++] = '#';
Manacher();
printf("%d\n", mx);
return 0;
} 今天刚刚学了回文自动机,又写了一遍,充分证实了Manacher的复杂度是O(n)的并且回文自动机常数的确巨小。下面一个板子
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 5;
int mx;
namespace PLD {
char s[maxn];
int trie[maxn][26], num, arr[maxn], sum[maxn], fail[maxn], len[maxn];
int cnt, last, pos;
void init() {
cnt = 1, last = 0;
len[0] = 0, len[1] = -1;
fail[0] = 1, pos = 0;
}
int getfail(int p) {
while(p != 1 && s[pos - len[p] - 1] != s[pos])
p = fail[p];
return p;
}
void add(int x) {
int id = s[x] - 'a';
int p = getfail(last);
if(!trie[p][id]) {
int now = ++cnt;
fail[now] = trie[getfail(fail[p])][id];
mx = max(len[now] = len[p] + 2, mx);
trie[p][id] = now;
}
last = trie[p][id];
++sum[last];
}
void push_up() {
for(register int i = cnt; i >= 2; --i)
sum[fail[i]] += sum[i];
}
void create() {
int len = strlen(s);
for(register int i = 0; i < len; ++i)
pos = i, add(i);
push_up();
}
}
int main() {
PLD::init();
scanf("%s", PLD::s);
PLD::create();
printf("%d", mx);
return 0;
}
rockdu
没有帐号? 立即注册