partial Section 2.4

master
大蒟蒻 9 years ago
parent 582592d40d
commit 23652daf61

@ -0,0 +1,30 @@
#include <cstdio>
#include <cstring>
inline int min(int a, int b) { return a < b ? a : b; }
inline int max(int a, int b) { return a > b ? a : b; }
char buf[1000100], str[2000200];
int R[2000200], T;
int main()
{
while (scanf("%s", buf), buf[0] != 'E')
{
int m = int(strlen(buf)), n = 0;
str[n++] = '!';
str[n++] = '#';
for (int i = 0; i < m; i++)
str[n++] = buf[i], str[n++] = '#';
str[n++] = '#';
str[n++] = '?';
int p = 0, mx = 0, ans = 0;
for (int i = 1; i < n; i++)
{
R[i] = mx > i ? min(R[2 * p - i], mx - i) : 1;
while (str[i + R[i]] == str[i - R[i]]) R[i]++;
if (R[i] + i > mx)
mx = i + R[p = i];
ans = max(ans, R[i]);
}
printf("Case %d: %d\n", ++T, ans - 1);
}
return 0;
}

@ -0,0 +1,78 @@
#include <cstdio>
#include <cstring>
struct node
{
node *trans[26], *fail;
int cnt;
} nodes[500010], virt;
node *que[500010];
int tot;
node *root;
node *new_node() { return &nodes[tot++]; }
void insert(char *str)
{
node *cur = root;
for (; *str; str++)
{
if (cur->trans[*str - 'a'] == 0)
cur->trans[*str - 'a'] = new_node();
cur = cur->trans[*str - 'a'];
}
cur->cnt++;
}
void buildFail()
{
int h = 0, t = 0;
root->fail = &virt;
que[t++] = root;
while (h < t)
{
node *cur = que[h++];
for (int i = 0; i < 26; i++)
{
node *f = cur->fail;
while (f->trans[i] == 0) f = f->fail;
f = f->trans[i];
if (cur->trans[i])
(que[t++] = cur->trans[i])->fail = f;
else
cur->trans[i] = f;
}
}
}
char buf[1000010];
int vis[500010];
int main()
{
memset(vis, -1, sizeof(vis));
int T, n;
scanf("%d", &T);
while (T--)
{
memset(nodes, 0, sizeof(nodes));
tot = 0, root = new_node();
for (int i = 0; i < 26; i++) virt.trans[i] = root;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%s", buf);
insert(buf);
}
buildFail();
scanf("%s", buf);
node *cur = root, *tmp;
int ans = 0;
for (char *ch = buf; *ch; ch++)
{
tmp = cur = cur->trans[*ch - 'a'];
while (tmp != &virt && vis[tmp - nodes] != T)
{
vis[tmp - nodes] = T;
ans += tmp->cnt;
tmp = tmp->fail;
}
}
printf("%d\n", ans);
}
return 0;
}

@ -0,0 +1,30 @@
#include <cstdio>
#include <cstring>
inline int min(int a, int b) { return a < b ? a : b; }
inline int max(int a, int b) { return a > b ? a : b; }
char buf[1000100], str[2000200];
int R[2000200], T;
int main()
{
while (scanf("%s", buf), buf[0] != 'E')
{
int m = int(strlen(buf)), n = 0;
str[n++] = '!';
str[n++] = '#';
for (int i = 0; i < m; i++)
str[n++] = buf[i], str[n++] = '#';
str[n++] = '#';
str[n++] = '?';
int p = 0, mx = 0, ans = 0;
for (int i = 1; i < n; i++)
{
R[i] = mx > i ? min(R[2 * p - i], mx - i) : 1;
while (str[i + R[i]] == str[i - R[i]]) R[i]++;
if (R[i] + i > mx)
mx = i + R[p = i];
ans = max(ans, R[i]);
}
printf("Case %d: %d\n", ++T, ans - 1);
}
return 0;
}

@ -168,5 +168,11 @@ $n$个基因片段,每个长度为$m$,输出$n$行表示重复出现$i$次$(
\paragraph{练习题}
\subparagraph{\href{http://acm.hdu.edu.cn/showproblem.php?pid=2222}{HDU2222} - Keywords Search}
AC 自动机模板题,注意统计答案时,每个节点只能统计一次不要重复统计。
\codeinput[Keywords Search]{assets/day2/poj3630.cpp}
\codeinput[Keywords Search]{assets/day2/hdu2222.cpp}
\subsection{Manacher}
求出字符串每一位的回文半径,算法流程奥妙重重,不易让常人理解,然后我就抄了份板子改了改,然后就比讲义上的标程快了$20\%$
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=3974}{POJ3974} - Palindrome}
Manacher 模板题
\codeinput[Palindrome]{assets/day2/poj3974.cpp}
\end{document}
Loading…
Cancel
Save