# 【BZOJ2434】[NOI2011]阿狸的打字机

bzoj

## 题解

$70pts$代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int MAX_N = 2e5 + 5;
char s[MAX_N];
int N, tot, nd[MAX_N], ans[MAX_N], sum[MAX_N];
struct Trie { int ch[26], fail, fa, End; } t[MAX_N];
void build() {
static queue<int> que;
for (int i = 0; i < 26; i++) if (t[0].ch[i]) que.push(t[0].ch[i]), t[t[0].ch[i]].fail = 0;
while (!que.empty()) {
int o = que.front(); que.pop();
for (int i = 0; i < 26; i++) {
if (t[o].ch[i]) t[t[o].ch[i]].fail = t[t[o].fail].ch[i], que.push(t[o].ch[i]);
else t[o].ch[i] = t[t[o].fail].ch[i];
}
}
}
int query(int y) {
int res = 0;
for (int o = nd[y]; o; o = t[o].fa)
for (int x = o; x; x = t[x].fail) if (t[x].End) ++sum[t[x].End];
return res;
}
struct Query { int x, y, id; } q[MAX_N];
bool operator < (const Query l, const Query r) { return l.y < r.y; }

int main () {
scanf("%s", s + 1);
for (int o = 0, i = 1, l = strlen(s + 1); i <= l; i++) {
if ('a' <= s[i] && s[i] <= 'z') {
if (!t[o].ch[s[i] - 'a']) t[o].ch[s[i] - 'a'] = ++tot, t[tot].fa = o;
o = t[o].ch[s[i] - 'a'];
}
if (s[i] == 'B') o = t[o].fa;
if (s[i] == 'P') nd[++N] = o, t[o].End = N;
}
build();
int M; scanf("%d", &M);
for (int i = 1; i <= M; i++) scanf("%d", &q[i].x), scanf("%d", &q[i].y), q[i].id = i;
sort(&q[1], &q[M + 1]);
for (int i = 1, j = 1; i <= M; i = j) {
query(q[i].y);
while (q[j].y == q[i].y) ans[q[j].id] = sum[q[j].x], ++j;
fill(&sum[1], &sum[N + 1], 0);
}
for (int i = 1; i <= M; i++) printf("%d\n", ans[i]);
return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int MAX_N = 2e5 + 5;
char s[MAX_N];
int N, tot, nd[MAX_N], ans[MAX_N];
struct Trie { int ch[26], cpy[26], fail, fa, End; } t[MAX_N];
void build() {
static queue<int> que;
for (int i = 0; i < 26; i++) if (t[0].ch[i]) que.push(t[0].ch[i]), t[t[0].ch[i]].fail = 0;
while (!que.empty()) {
int o = que.front(); que.pop();
for (int i = 0; i < 26; i++) {
if (t[o].ch[i]) t[t[o].ch[i]].fail = t[t[o].fail].ch[i], que.push(t[o].ch[i]);
else t[o].ch[i] = t[t[o].fail].ch[i];
}
}
}
struct Graph { int to, next; } e[MAX_N << 1]; int fir[MAX_N], e_cnt = 0;
void clearGraph() { memset(fir, -1, sizeof(fir)); e_cnt = 0; }
void Add_Edge(int u, int v) { e[e_cnt] = (Graph){v, fir[u]}, fir[u] = e_cnt++; }
struct Query { int x, id; } ;
vector<Query> vec[MAX_N];
int tim, L[MAX_N], R[MAX_N];
void dfs(int x) {
L[x] = ++tim;
for (int i = fir[x]; ~i; i = e[i].next) dfs(e[i].to);
R[x] = tim;
}
int c[MAX_N];
inline int lb(int x) { return x & -x; }
void add(int x, int v) { while (x <= tim) c[x] += v, x += lb(x); }
int sum(int x) { int res = 0; while (x > 0) res += c[x], x -= lb(x); return res; }
void DFS(int x) {
if (t[x].End)
for (vector<Query> :: iterator ite = vec[t[x].End].begin(); ite != vec[t[x].End].end(); ++ite)
ans[ite->id] = sum(R[nd[ite->x]]) - sum(L[nd[ite->x]] - 1);
for (int i = 0; i < 26; i++)
if (t[x].cpy[i]) DFS(t[x].cpy[i]);
}
int main () {
scanf("%s", s + 1);
for (int o = 0, i = 1, l = strlen(s + 1); i <= l; i++) {
if ('a' <= s[i] && s[i] <= 'z') {
if (!t[o].ch[s[i] - 'a']) t[o].ch[s[i] - 'a'] = ++tot, t[tot].fa = o;
o = t[o].ch[s[i] - 'a'];
}
if (s[i] == 'B') o = t[o].fa;
if (s[i] == 'P') nd[++N] = o, t[o].End = N;
}
for (int i = 0; i <= tot; i++)
for (int o = 0; o < 26; o++) t[i].cpy[o] = t[i].ch[o];
build(); clearGraph();
for (int i = 1; i <= tot; i++) Add_Edge(t[i].fail, i);
dfs(0);
int M; scanf("%d", &M);
for (int i = 1; i <= M; i++) {
int x, y; scanf("%d%d", &x, &y);
vec[y].push_back((Query){x, i});
}
DFS(0);
for (int i = 1; i <= M; i++) printf("%d\n", ans[i]);
return 0;
}


posted @ 2019-01-09 10:40  heyujun  阅读(257)  评论(0编辑  收藏  举报