#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define ls rt<<1
#define rs rt<<1|1
#define Mid int m = (l + r) >> 1;
#define X first
#define Y second
const int mod = 1e9 + 7;
const int maxn = 100005;
typedef long long LL;
typedef pair<int, int> PII;
LL _26[maxn];
void init() {
int i;
_26[0] = 1;
for (i = 1; i < maxn; i++)
_26[i] = _26[i - 1] * 26 % mod;
}
struct Edge {
int v, w, next;
Edge(int v, int w, int next) :
v(v), w(w), next(next) {
}
Edge() {
}
} edge[maxn << 2];
int n, m;
int head[maxn], E;
void add(int s, int t, int w) {
edge[E] = Edge(t, w, head[s]);
head[s] = E++;
edge[E] = Edge(s, w, head[t]);
head[t] = E++;
}
vector<int> res[maxn];
int val[maxn], pos[maxn], dep[maxn], dfn[maxn];
int len[maxn], max_d[maxn], sum[maxn], rk[maxn];
int Time;
void edge_init() {
int i;
E = 0;
memset(head, -1, sizeof(head));
}
struct trie {
int ch[maxn][26], RK[maxn], sz;
int newNode() {
memset(ch[sz], 0, sizeof(ch[sz]));
RK[sz] = 0;
return sz++;
}
void dfs(int u, int fa, int rt) {
dfn[u] = ++Time;
max_d[u] = dep[u] = dep[fa] + 1;
res[dep[u]].push_back(dfn[u]);
pos[u] = res[dep[u]].size();
int i, v, w;
for (i = head[u]; ~i; i = edge[i].next) {
v = edge[i].v;
w = edge[i].w;
if (v == fa) continue;
val[v] = ((LL) val[u] * 26 + w) % mod;
if (!ch[rt][w]) ch[rt][w] = newNode();
dfs(v, u, ch[rt][w]);
max_d[u] = max(max_d[u], max_d[v]);
}
}
void bfs(){
int id = 1, i;
queue <int> q;
q.push(0);
RK[0] = 1;
while(!q.empty()) {
int u = q.front(); q.pop();
for(i = 0; i < 26; i++) {
int v = ch[u][i];
if(v) {
RK[v] = ++id;
q.push(v);
}
}
}
}
void cal(int u, int fa, int rt) {
int i, v, w;
for(i = head[u]; ~i; i = edge[i].next) {
v = edge[i].v;
w = edge[i].w;
if(v == fa) continue;
rk[v] = RK[ch[rt][w]];
cal(v, u, ch[rt][w]);
}
}
void gao() {
sz = 0;
newNode();
Time = 0;
max_d[1] = dep[1] = 1;
val[1] = 0;
for (int i = 0; i <= n; i++)
res[i].clear();
dfs(1, 0, 0);
bfs();
rk[1] = 1;
cal(1, 0, 0);
}
} trie;
struct segtree {
PII sum[maxn << 2];
void pushUp(int rt) {
sum[rt] = max(sum[ls], sum[rs]);
}
void insert(int p, int idx, int v, int l = 1, int r = n, int rt = 1) {
if (l == r) {
sum[rt] = make_pair(v, idx);
return;
}
Mid
;
if (p <= m)
insert(p, idx, v, lson);
else
insert(p, idx, v, rson);
pushUp(rt);
}
PII query(int L, int R, int l = 1, int r = n, int rt = 1) {
if (L <= l && r <= R)
return sum[rt];
Mid
;
PII ret = make_pair(-1, -1);
if (L <= m)
ret = max(ret, query(L, R, lson));
if (R > m)
ret = max(ret, query(L, R, rson));
return ret;
}
void print(int l=1, int r=n, int rt=1) {
if(l ==r) {
printf("~~~~~%d %d\n", sum[rt].first, sum[rt].second);
return;
}
Mid;
print(lson);
print(rson);
}
} T;
void debug() {
int i;
for(i = 1; i <= n; i++)
printf("%d ", rk[i]);
puts("");
}
void solve() {
int i;
trie.gao();
sum[0] = 0;
for (i = 1; i <= n; i++)
sum[i] = sum[i - 1] + res[i].size();
for (i = 1; i <= n; i++)
sum[i] -= res[i].size();
for (i = 1; i <= n; i++) {
int x = sum[dep[i]] + pos[i];
T.insert(x, i, rk[i]);
}
}
char buf[4];
int x, y, z;
int main() {
// freopen("1002.in", "r", stdin);
// freopen("my1002.out", "w", stdout);
int i, j, cas;
init();
scanf("%d", &cas);
while (cas--) {
scanf("%d", &n);
edge_init();
for (i = 1; i < n; i++) {
scanf("%d%d%s", &x, &y, buf);
z = buf[0] - 'a';
add(x, y, z);
}
solve();
// debug();
// T.print();
scanf("%d", &m);
int u, step;
while (m--) {
scanf("%d%d", &u, &step);
if (!step) {
puts("0");
continue;
}
int q_dep = step + dep[u];
if (max_d[u] < q_dep)
puts("IMPOSSIBLE");
else {
int ldfn = res[dep[u]][pos[u] - 1];
int rdfn;
if (pos[u] == (int) res[dep[u]].size())
rdfn = n + 1;
else
rdfn = res[dep[u]][pos[u]];
int l = lower_bound(res[q_dep].begin(), res[q_dep].end(), ldfn)
- res[q_dep].begin() + 1;
int r = lower_bound(res[q_dep].begin(), res[q_dep].end(), rdfn)
- res[q_dep].begin();
l += sum[q_dep];
r += sum[q_dep];
// printf("l = %d r = %d\n", l, r);
int ans = (val[T.query(l, r).second]
- (LL) val[u] * _26[step] % mod) % mod;
if (ans < 0)
ans += mod;
printf("%d\n", ans);
}
}
}
return 0;
}
hdu 4601 Letter Tree 线段树
最新推荐文章于 2017-07-29 09:59:00 发布