題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4605
多校第一場的題,賽後看了題解感覺這題也不是很難, 比賽時忙於別的題目這題都沒看, 還是經驗不足啊, 這道題就是利用dfs結合樹狀數組或者平衡樹(可以支持查找當前集合小於val的元素個數的數據結構)統計從根結點到當前點的一條樹鏈上的權值,向下遞歸時插入回溯時再刪除, 需要把所有查詢離線處理, 每次到達一個節點時先處理和這個點相關的所有查詢, 然後遞歸處理左右兒子節點。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <set>
#include <map>
using namespace std;
#define fi first
#define se second
#define mp make_pair
const int N = 100005;
const int M = N << 1;
int n;
int head[N], to[M], next[M];
int tot;
map<int, int> Map;
vector<pair<int, int> > vec[N];
bool flag[N];
int W[N];
inline int lowbit(int t) {
return t & (-t);
}
struct BIT {
int c[N << 2];
int n;
void init(int m) { // < m
this->n = m;
fill(c, c + n + 1, 0);
}
void add(int p, int v) {
while (p < n) {
c[p] += v;
p += lowbit(p);
}
}
int sum(int m) {
int res = 0;
while (m) {
res += c[m];
m -= lowbit(m);
}
return res;
}
bool find(int v) {
return sum(v) - sum(v - 1) >= 1;
}
void insert(int v) {
add(v, 1);
}
void remove(int v) {
add(v, -1);
}
int lower(int v) {
return sum(v - 1);
}
}T1, T2;
void init() {
for (int i = 1; i <= n; i++) {
head[i] = -1;
}
tot = 0;
}
void add(int u, int v) {
to[tot] = v, next[tot] = head[u], head[u] = tot++;
}
int a1[N], a2[N], b1[N], b2[N];
void dfs(int u, int L, int R) {
int sz = vec[u].size();
pair<int, int> tmp;
int id, val;
for (int i = 0; i < sz; i++) {
tmp = vec[u][i];
id = tmp.se;
val = tmp.fi;
if (T1.find(val) || T2.find(val)) {
flag[id] = 1;
}
else {
a2[id] = T1.lower(val);
a1[id] = L - a2[id];
b2[id] = T2.lower(val);
b1[id] = R - b2[id];
}
}
for (int i = head[u]; i != -1; i = next[i]) {
int v = to[i];
if (i == head[u]) {
T1.insert(W[u]);
dfs(v, L + 1, R);
T1.remove(W[u]);
}
else {
T2.insert(W[u]);
dfs(v, L, R + 1);
T2.remove(W[u]);
}
}
}
int tmp[N * 2];
pair<int, int> Q[N];
int c;
int main() {
int test, m, q, u, l, r, v;
scanf("%d", &test);
while (test--) {
scanf("%d", &n);
init();
c = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", W + i);
vec[i].clear();
tmp[c++] = W[i];
}
scanf("%d", &m);
while (m--) {
scanf("%d%d%d", &u, &l, &r);
add(u, r);
add(u, l);
}
scanf("%d", &q);
for (int i = 0; i < q; i++) {
scanf("%d%d", &Q[i].fi, &Q[i].se);
tmp[c++] = Q[i].se;
flag[i] = 0;
}
sort(tmp, tmp + c);
c = unique(tmp, tmp + c) - tmp;
Map.clear();
for (int i = 0; i < c; i++)
Map[tmp[i]] = i + 1;
for (int i = 1; i <= n; i++)
W[i] = Map[W[i]];
pair<int, int> t;
for (int i = 0; i < q; i++) {
t = Q[i];
vec[t.fi].push_back(mp(Map[t.se], i));
}
T1.init(c + 1), T2.init(c + 1);
dfs(1, 0, 0);
int x, y;
for (int i = 0; i < q; i++) {
if (flag[i]) {
puts("0");
}
else {
y = a1[i] + 3 * a2[i] + b1[i] + 3 * b2[i];
x = b2[i];
printf("%d %d\n", x, y);
}
}
}
return 0;
}