# 【BZOJ 2434】【NOI 2011】阿狸的打字机 fail树

$fail树$的性质完全不知道啊，只好现学，，，

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200003
#define lowbit(x) (x & (-x))
using namespace std;
inline int getint() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = k * 10 + c - '0';
return k * fh;
}
struct node {
int nxt, to;
} E[N * 26];
int fa[N], watch[N], c[N][26], cnt = 0, tot = 0, point[N];
int fail[N], L[N], R[N], C[N], m, ans[N];
inline void _(char *s) {
int len = strlen(s), now = 0;
for(int i = 0; i < len; ++i){
if (s[i] >= 'a' && s[i] <= 'z') {
int t = s[i] - 'a';
if (!c[now][t])
c[now][t] = ++cnt;
fa[cnt] = now;
now = cnt;
}else
if (s[i] == 'P')
watch[++tot] = now;
else
now = fa[now];
}
}
inline void ins(int x, int y) {E[++cnt].nxt = point[x]; E[cnt].to = y; point[x] = cnt;}
inline void __() {
cnt = 0;
queue <int> q;
for(int t = 0; t < 26; ++t)
if (c[0][t])
q.push(c[0][t]), ins(0, c[0][t]);
while (!q.empty()) {
int now = q.front();
q.pop();
for(int t = 0; t < 26; ++t)
if (!c[now][t])
c[now][t] = c[fail[now]][t];
else {
int u = c[now][t];
fail[u] = c[fail[now]][t];
ins(fail[u], u);
q.push(u);
}
}
}
inline void ___(int x) {
L[x] = ++cnt;
for(int tmp = point[x]; tmp; tmp = E[tmp].nxt)
___(E[tmp].to);
R[x] = cnt;
}

inline void inc(int pos, int num) {
for(; pos <= cnt; pos += lowbit(pos))
C[pos] += num;
}
inline int sum(int pos) {
int s = 0;
for(; pos > 0; pos -= lowbit(pos))
s += C[pos];
return s;
}

struct nnode {
int x, y, id;
} A[N];
inline bool cmp(nnode n1, nnode n2) {return n1.y < n2.y;}
int main() {
char s[N << 1];
scanf("%s", s);
_(s);
__();

cnt = 0;
___(0);

for(int i = 1; i <= m; ++i)
sort(A + 1, A + m + 1, cmp);

int len = strlen(s), now = 0, con =1;
tot = 0;
for(int i = 0; i < len; ++i) {
if (s[i] >= 'a' && s[i] <= 'z')
now = c[now][s[i] - 'a'], inc(L[now], 1);
else
if (s[i] == 'P') {
if (++tot == A[con].y) {
for(; tot == A[con].y; ++con)
ans[A[con].id] = sum(R[watch[A[con].x]]) - sum(L[watch[A[con].x]] - 1);
}
} else
inc(L[now], -1), now = fa[now];
}

for(int i = 1; i <= m; ++i)
printf("%d\n", ans[i]);
return 0;
}


posted @ 2016-04-05 20:42  abclzr  阅读(174)  评论(0编辑  收藏  举报