对于某个询问(u, x),首先判断从根到 u的路径上是否有点权等于x。若存在,则到达当前点
的概率是0。
不妨定义往左走的路径为“左路径”,往右走的路径称为“右路径”。设左路径上大于 x的点权
有a1个,小于 x的点权有a2个,则通过所有左路径并到达节点 u的概率是p1 = (1/2)^a1 *(1/8)^a2
类似地,设右路径上大于x的点权有b1个,小于x的点权有b2个,则通过所有右路径并到达
点u的概率p2 = (1/2)^b1 * (7/8)^b2
。最后的答案就是p = p1*p2.
求根到u的路径上大于(小于/等于)x的点权数量,可以在离线之后对树做一次 dfs,并用
树状数组维护当前路径中的所有点权。总复杂度是O(QlogN).
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
const int MAXN = 100100;
int c[2*MAXN][2];
int tree[MAXN][2];
map<int,int>mp;
vector<int>vv[MAXN];
int num[2*MAXN];
int w[MAXN];
bool vis[MAXN],judge[MAXN];
int tot;
struct query
{
int x,u;
int a,b;
}q[MAXN];
int lowbit(int x)
{
return x&(-x);
}
void updata(int x,int p,int d)
{
for(;x<=tot;x+=lowbit(x)) c[x][p]+=d;
}
int sum(int x,int p)
{
int res=0;
for(;x>0;x-=lowbit(x)) res+=c[x][p];
return res;
}
void dfs(int u)
{
int siz=vv[u].size();
for(int i=0;i<siz;i++)
{
int it=vv[u][i];
int t=mp[q[it].x];
if(sum(t,0)-sum(t-1,0)||sum(t,1)-sum(t-1,1))
{
q[it].a=-1;
q[it].b=-1;
continue;
}
/* if(vis[t])
{
judge[it]=1;
continue;
}*/
q[it].a=sum(t-1,1);
q[it].b=sum(t-1,0)*3+(sum(tot,0)-sum(t,0))+sum(t-1,1)*3+(sum(tot,1)-sum(t,1));
}
if(tree[u][0])
{
int t=mp[w[u]];
vis[t]=1;
updata(t,0,1);
dfs(tree[u][0]);
updata(t,0,-1);
updata(t,1,1);
dfs(tree[u][1]);
updata(t,1,-1);
vis[t]=0;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
mp.clear();
memset(c,0,sizeof(c));
memset(tree,0,sizeof(tree));
memset(vis,0,sizeof(vis));
memset(judge,0,sizeof(judge));
int n,m,Q;
scanf("%d",&n);
for(int i=0;i<=n;i++) vv[i].clear();
int cnt=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&w[i]);
num[cnt++]=w[i];
}
scanf("%d",&m);
while(m--)
{
int u,a,b;
scanf("%d%d%d",&u,&a,&b);
tree[u][0]=a;
tree[u][1]=b;
vis[a]=1;
vis[b]=1;
}
scanf("%d",&Q);
tot=0;
for(int i=1;i<=Q;i++)
{
//int v,x;
scanf("%d%d",&q[i].u,&q[i].x);
vv[q[i].u].push_back(i);
num[cnt++]=q[i].x;
}
sort(num,num+cnt);
for(int i=0;i<cnt;i++)
{
if(mp[num[i]]) continue;
mp[num[i]]=++tot;
}
int u;
for(int i=1;i<=n;i++) if(!vis[i])
{
u=i;
break;
}
memset(vis,0,sizeof(vis));
dfs(u);
for(int i=1;i<=Q;i++)
{
if(q[i].a==-1&&q[i].b==-1) puts("0");
else
{
printf("%d %d\n",q[i].a,q[i].b);
}
}
}
}