记录编号 381650 评测结果 AAAAAAAAAA
题目名称 [NOI 2011]阿狸的打字机 最终得分 100
用户昵称 GravatarRapiz 是否通过 通过
代码语言 C++ 运行时间 0.320 s
提交时间 2017-03-12 12:44:11 内存使用 15.28 MiB
显示代码纯文本
#include <cstdio>
#include <vector>
const int L = 1e5 + 10;
int m, ch[L][26], fail[L], q[L], h, t, dfn[L], sz[L], clk, lines, pos[L], ans[L], trie_cnt, a[L];
std::vector<int> to[L];
struct QU{int x, id;};
std::vector<QU> qu[L];
char s[L];
inline int lowbit(int x) {return x&-x;}
inline void add(int p, int v) {for (;p <= clk; p += lowbit(p)) a[p] += v;}
inline int pre(int p) {
	int s = 0;
	for (;p; p -= lowbit(p)) s += a[p];
	return s;
}
inline int sum(int l, int r) {return pre(r) - pre(l - 1);}
int init(int u) {
	dfn[u] = ++clk;
	for (int i = 0; i < (int)to[u].size(); i++)
		sz[u] += init(to[u][i]);
	return sz[u] += 1;
}
void dfs(int u) {
	add(dfn[u], 1);
	for (int i = 0; i < (int)qu[u].size(); i++) {
		QU& qq = qu[u][i];
		ans[qq.id] = sum(dfn[qq.x], dfn[qq.x] + sz[qq.x] - 1);
	}
	for (int i = 0; i < 26; i++) if (ch[u][i]) dfs(ch[u][i]);
	add(dfn[u], -1);
}
int main() {
	freopen("noi2011_type.in", "r", stdin);
	freopen("noi2011_type.out", "w", stdout);
	scanf("%s", s);
	int now = 0;
	q[t++] = now;
	for (char* p = s; *p; p++) {
		if (*p == 'P') pos[++lines] = now;
		else if (*p == 'B') now = q[--t];	
		else {
			if (!ch[now][*p - 'a']) ch[now][*p - 'a'] = ++trie_cnt;
			q[t++] = now;
			now = ch[now][*p - 'a'];
		}
	}
	t = 0;
	for (int i = 0; i < 26; i++) if (ch[0][i]) q[t++] = ch[0][i];
	while (h < t) {
		int x = q[h++];
		to[fail[x]].push_back(x);
		for (int i = 0; i < 26; i++) if (ch[x][i]) {
			q[t++] = ch[x][i];
			int p = fail[x];
			while (p && !ch[p][i]) p = fail[p];
			fail[ch[x][i]] = ch[p][i];
		}
	}
	scanf("%d", &m);
	for (int i = 1; i <= m; i++) {
		int x, y;scanf("%d%d", &x, &y);
		x = pos[x], y = pos[y];
		qu[y].push_back((QU){x, i});
	}
	init(0), dfs(0);
	for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
}