n个点的树,每个点有一个权值。1为根,每个点要么有2个儿子,要么没有儿子。
Q次询问,每次给节点v,和数X,一个球从根往下走:
1.X = w[i]或i没有儿子,球停下
2.X < w[i],球有1/2可能往左走,1/2可能右走
3.X > W[I],球有1/8可能往左走,7/8可能右走
统计根到v的路径上,(往左走、往右走)*(大于x、小于x)的个数
则到达v点的可能性为(1/2)^(左&小于) * (1/2)^(左&大于) * (1/8)^(左&小于) * (7/8)^(左&大于)
//如果路径上有x == w[i]则之后可能性都为0
在dfs时用树状数组统计,每个时候树状数组中统计的东西,就是根到v上节点的信息。
#include <cstdio>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e5 + 5;
int T,N,M,Q;
int u,a,b;
struct node{
int l = -1,r = -1;
}ns[maxn];
int opv[maxn];
struct num{
int x,id;
}opx[maxn],w[maxn];
map<int,int> id;
const int maxtr = maxn << 1;
int trl[maxtr + 10],trr[maxtr + 10];//记录wi出现的个数
vector<int> mpv[maxn];
int cnt7[maxn],cnt2[maxn];//cnt7[]作为分母,为-1表示答案为0,>=0表示7的指数
int p;
void add(int tr[],int x,int d)
{
while(x < maxtr){
tr[x] += d;
x += (x & -x);
}
}
int query(int tr[],int x)
{
// printf("query x = %d\n",x);
int ans = 0;
while(x){
ans += tr[x];
x -= (x & -x);
}
return ans;
}
void dfs(int s)
{
for(int i = 0;i < mpv[s].size();i ++){
int opid = mpv[s][i];//离散化后的数字
int x = opx[opid].id;
int e = query(trl,x) - query(trl,x - 1) + query(trr,x) - query(trr,x - 1);
if(e) {cnt7[opid] = -1;continue;}//如果之前有等于x,那么一定为0
int a = query(trl,x - 1);//左儿子w[i] < X的个数
int b = query(trl,p) - query(trl,x);//左儿子w[i] > X的个数
int c = query(trr,x - 1);//右儿子w[i] < X的个数
int d = query(trr,p) - query(trr,x);//右儿子w[i] > X的个数
cnt7[opid] = c;
cnt2[opid] = b + d + 3 * (a + c);
// ans[opid] = (1/2)^b * (1/8)^a * (1/2)^d * (7/8)^c
}
if(ns[s].l != -1) {
add(trl,w[s].id,1);dfs(ns[s].l);add(trl,w[s].id,-1);
add(trr,w[s].id,1);dfs(ns[s].r);add(trr,w[s].id,-1);
}
}
void init(){
id.clear();
for (int i = 1; i <= N; i ++) {
ns[i].l = ns[i].r = -1;
mpv[i].clear();
}
memset(trl, 0, sizeof(trl));
memset(trr, 0, sizeof(trr));
}
int main()
{
scanf("%d",&T);
while (T --) {
scanf("%d",&N);init();
for(int i = 1;i <= N;i ++) {scanf("%d",&w[i].x);id[w[i].x];}
scanf("%d",&M);
for(int i = 1;i <= M;i ++){
scanf("%d%d%d",&u,&a,&b);
ns[u].l = a;ns[u].r = b;
}
scanf("%d",&Q);
for(int i = 1;i <= Q;i ++){
scanf("%d%d",&opv[i],&opx[i].x);
id[opx[i].x];
}
p = 1;
for(auto &a:id) a.second = p ++;
for(int i = 1;i <= N;i ++) w[i].id = id[w[i].x];
for(int i = 1;i <= Q;i ++) {
opx[i].id = id[opx[i].x];
mpv[opv[i]].push_back(i);
}
dfs(1);
for(int i = 1;i <= Q;i ++){
if(cnt7[i] == -1) printf("0\n");
else{
printf("%d %d\n",cnt7[i],cnt2[i]);
}
}
}
return 0;
}