您的位置:首页 > 其它

【ZOJ】3228 Searching the String

2012-08-07 00:30 351 查看
#include<cstdio>
#include<cstring>
#include<queue>
#define MAXN 100010
#define MAXM 26
#define INF 123456789
using namespace std;
struct Trie {
int fail, pos[2], cnt[2], len, next[MAXM];
void Init() {
len = fail = pos[0] = pos[1] = cnt[0] = cnt[1] = 0;
memset(next, 0, sizeof(next));
}
};
Trie tree[MAXN << 2];
char str[MAXN], s[MAXM];
int size, ans[MAXN], pos[MAXN], vis[MAXN];
inline int GET(char ch) {
return ch - 'a';
}
void Insert(int pos, int x) {
int now, i, t;
for (now = i = 0; s[i]; i++) {
t = GET(s[i]);
if (!tree[now].next[t]) {
tree[++size].Init();
tree[now].next[t] = size;
}
now = tree[now].next[t];
}
tree[now].len = i;
tree[now].pos[x] = pos;
tree[now].cnt[x]++;
}
int Find(int x) {
int now, i, t;
for (now = i = 0; s[i]; i++) {
t = GET(s[i]);
if (!tree[now].next[t])
return 0;
now = tree[now].next[t];
}
return tree[now].pos[x];
}
void BFS() {
int now, i, p;
queue<int> q;
q.push(0);
while (!q.empty()) {
now = q.front();
q.pop();
for (i = 0; i < MAXM; i++) {
if (tree[now].next[i]) {
p = tree[now].next[i];
q.push(p);
if (now)
tree[p].fail = tree[tree[now].fail].next[i];
} else
tree[now].next[i] = tree[tree[now].fail].next[i];
}
}
}
void Match() {
int now, t, p, i;
for (now = i = 0; str[i]; i++) {
t = GET(str[i]);
now = tree[now].next[t];
for (p = now; p; p = tree[p].fail) {
if (tree[p].cnt[0])
ans[tree[p].pos[0]] += tree[p].cnt[0];
if (tree[p].cnt[1] && i - vis[tree[p].pos[1]] >= tree[p].len) {
vis[tree[p].pos[1]] = i;
ans[tree[p].pos[1]] += tree[p].cnt[1];
}
}
}
}
int main() {
int n, i, x, ca = 1;
while (~scanf(" %s", str)) {
size = 0;
tree[0].Init();
scanf("%d", &n);
for (i = 1; i <= n; i++) {
ans[i] = 0;
vis[i] = -INF;
scanf("%d %s", &x, s);
pos[i] = Find(x);
if (!pos[i]) {
pos[i] = i;
Insert(i, x);
}
}
BFS();
Match();
printf("Case %d\n", ca++);
for (i = 1; i <= n; i++)
printf("%d\n", ans[pos[i]]);
putchar('\n');
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: