解法:
在对树的dfs同时维护两颗线段树,记录到达当前节点经过左路径和右路径上的权值,然后注意回退的时候要删除。。。
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<algorithm> 5 #pragma comment(linker, "/STACK:102400000,102400000") 6 using namespace std; 7 #define lson l,m,n<<1 8 #define rson m+1,r,n<<1|1 9 const int N = (int)2e5+10; 10 struct Query{ 11 int x,index; 12 Query(int _x,int _index):x(_x),index(_index){} 13 }; 14 vector<int>G[N]; 15 vector<Query>V[N]; 16 int w[N]; 17 pair<int,int>ans[N]; 18 struct segtree{ 19 int s[N<<2]; 20 void pushup(int n){ 21 s[n] = s[n<<1] + s[n<<1|1]; 22 } 23 void build(int l,int r,int n){ 24 s[n] = 0; 25 if(l==r)return; 26 int m = (l+r)>>1; 27 build(lson);build(rson); 28 } 29 void update(int pos,int op,int l,int r,int n){ 30 if(l==r){ 31 if(op==0)s[n]--; 32 else s[n]++; 33 return; 34 } 35 int m = (l+r)>>1; 36 if(pos<=m)update(pos,op,lson); 37 else update(pos,op,rson); 38 pushup(n); 39 } 40 int query(int L,int R,int l,int r,int n){ 41 if(L==l&&R==r)return s[n]; 42 int m = (l+r)>>1; 43 if(R<=m)return query(L,R,lson); 44 else if(L>m)return query(L,R,rson); 45 else return query(L,m,lson)+query(m+1,R,rson); 46 } 47 }; 48 segtree left,right; 49 int X[N*2],all; 50 void dfs(int u){ 51 for(int i=0;i<V[u].size();i++){ 52 int hash = lower_bound(X+1,X+1+all,V[u][i].x) - X; 53 if(left.query(hash,hash,1,all,1)||right.query(hash,hash,1,all,1)){ 54 ans[V[u][i].index] = make_pair(-1,-1); 55 continue; 56 } 57 int a = left.query(1,hash-1,1,all,1); 58 int b = left.query(hash+1,all,1,all,1); 59 int c = right.query(1,hash-1,1,all,1); 60 int d = right.query(hash+1,all,1,all,1); 61 ans[V[u][i].index] = make_pair(c,3*a+b+3*c+d); 62 } 63 for(int i = 0;i<G[u].size();i++){ 64 int v = G[u][i]; 65 int hash = lower_bound(X+1,X+1+all,w[u]) - X; 66 if(i==0){ 67 left.update(hash,1,1,all,1); 68 dfs(v); 69 left.update(hash,0,1,all,1); 70 }else{ 71 right.update(hash,1,1,all,1); 72 dfs(v); 73 right.update(hash,0,1,all,1); 74 } 75 } 76 } 77 int main(){ 78 int T,n,m,q; 79 scanf("%d",&T); 80 while(T--){ 81 scanf("%d",&n); 82 int _cnt = 0; 83 for(int i=1;i<=n;i++){ 84 scanf("%d",&w[i]); 85 X[++_cnt] = w[i]; 86 } 87 for(int i=1;i<=n;i++)G[i].clear(),V[i].clear(); 88 scanf("%d",&m); 89 for(int i=1;i<=m;i++){ 90 int a,u,v; 91 scanf("%d%d%d",&a,&u,&v); 92 G[a].push_back(u); 93 G[a].push_back(v); 94 } 95 scanf("%d",&q); 96 for(int i=1;i<=q;i++){ 97 int x,v; 98 scanf("%d%d",&v,&x); 99 X[++_cnt] = x; 100 V[v].push_back(Query(x,i)); 101 } 102 X[++_cnt] = 0;X[++_cnt] = ~0u>>2; 103 sort(X+1,X+1+_cnt); 104 all = 1; 105 for(int i=2;i<=_cnt;i++) 106 if(X[i]!=X[i-1])X[++all] = X[i]; 107 left.build(1,all,1); 108 right.build(1,all,1); 109 dfs(1); 110 for(int i=1;i<=q;i++){ 111 if(ans[i].first==-1)printf("0 "); 112 else printf("%d %d ",ans[i].first,ans[i].second); 113 } 114 } 115 return 0; 116 }