hdu 4605 Magic Ball Game

解法:

  在对树的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 }
原文地址:https://www.cnblogs.com/silver-bullet/p/3227333.html