SPOJ QTREE-Query on a tree-树链剖分-边权

用每个点代表父节点到此点的边。建立一一映射后就可以用点权的方法处理了。

注意的是路径两端节点的处理

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <vector>
  4 
  5 using namespace std;
  6 
  7 const int maxn = 1e5+5;
  8 int val[maxn],dep[maxn],siz[maxn],top[maxn],id[maxn],son[maxn],fa[maxn];
  9 int topw,M;
 10 
 11 vector<int> G[maxn];
 12 struct Edge{
 13     int x,y,val;
 14 }e[maxn];
 15 
 16 void dfs_1(int u,int f,int d)
 17 {
 18     fa[u] = f;
 19     son[u] = 0;
 20     siz[u] = 1;
 21     dep[u] = d;
 22 
 23     for(int i=0;i<G[u].size();i++) if(G[u][i] != f )
 24     {
 25         dfs_1(G[u][i],u,d+1);
 26         siz[u] += siz[G[u][i]];
 27         if(siz[son[u] ] < siz[G[u][i] ])
 28         {
 29             son[u] = G[u][i];
 30         }
 31     }
 32 }
 33 
 34 void dfs_2(int u,int tp)
 35 {
 36     top[u] = tp;
 37     id[u] = ++topw;
 38     if(son[u]) dfs_2(son[u],tp);
 39     for(int i=0;i<G[u].size();i++) if(G[u][i] != fa[u] && G[u][i] != son[u])
 40     {
 41         dfs_2(G[u][i],G[u][i]);
 42     }
 43 }
 44 
 45 int N,T;
 46 
 47 void debug()
 48 {
 49     for(int i=1;i<=N;i++)
 50     {
 51         printf("%d siz:%d son:%d dep:%d fa:%d ",i,siz[i],son[i],dep[i],fa[i]);
 52         printf("top:%d id:%d\n",top[i],id[i]);
 53     }
 54 }
 55 
 56 /*-------------------------------------*/
 57 //segment Tree
 58 #define lson(x) (x<<1)
 59 #define rson(x) (x<<1|1)
 60 
 61 struct SegmentTree{
 62     int l,r,val;
 63 }sgtree[4*maxn];
 64 
 65 void pushup(int x)
 66 {
 67     sgtree[x].val = max(sgtree[lson(x)].val,sgtree[rson(x)].val);
 68 }
 69 
 70 void Build(int l,int r,int x)
 71 {
 72     sgtree[x].l = l;
 73     sgtree[x].r = r;
 74     if(l==r)
 75     {
 76         sgtree[x].val = val[l];
 77         return ;
 78     }
 79     int mid = (l+r)>>1;
 80     Build(l,mid,lson(x));
 81     Build(mid+1,r,rson(x));
 82     pushup(x);
 83 }
 84 
 85 void update(int x,int v,int add)
 86 {
 87     if(sgtree[x].l == sgtree[x].r)
 88     {
 89         sgtree[x].val = add;
 90         //printf("change:%d %d\n",v,sgtree[x].l);
 91         return ;
 92     }
 93     int mid = (sgtree[x].l+sgtree[x].r)>>1;
 94     if(v <= mid) update(lson(x),v,add);
 95     else         update(rson(x),v,add);
 96     pushup(x);
 97 }
 98 
 99 int query(int x,int l,int r)
100 {
101     if(sgtree[x].l >= l && sgtree[x].r <= r)
102     {
103         return sgtree[x].val;
104     }
105     int mid = (sgtree[x].l+sgtree[x].r)>>1;
106     int ans = 0;
107     if(l <= mid) ans = max(ans,query(lson(x),l,r));
108     if(r >  mid) ans = max(ans,query(rson(x),l,r));
109     return ans;
110 }
111 
112 int Find(int u,int v)
113 {
114     int ans = 0,fu = top[u],fv = top[v];
115     while(fu != fv)
116     {
117         if(dep[fu] < dep[fv])
118         {
119             swap(fu,fv);swap(u,v);
120         }
121         ans = max(ans,query(1,id[fu],id[u]));
122         u = fa[fu];
123         fu = top[u];
124     }
125     if(u == v) return ans;
126     if(dep[u]>dep[v]) swap(u,v);
127     return max(ans,query(1,id[son[u] ],id[v]));
128 }
129 
130 int main()
131 {
132     //freopen("input.in","r",stdin);
133     scanf("%d",&T);
134     while(T--)
135     {
136         scanf("%d",&N);
137         for(int i=1,a,b,c;i<N;i++)
138         {
139             scanf("%d%d%d",&a,&b,&c);
140             e[i].x = a;
141             e[i].y = b;
142             e[i].val = c;
143             G[a].push_back(b);
144             G[b].push_back(a);
145         }
146         topw = 0;
147         dfs_1(1,0,1);
148         dfs_2(1,1);
149         //debug();
150 
151         for(int i=1;i<N;i++)
152         {
153             if(dep[e[i].x] < dep[e[i].y]) swap(e[i].x,e[i].y);
154             val[id[e[i].x]] = e[i].val;
155         }
156 
157         Build(1,topw,1);
158         char op[100];
159         while(scanf("%s",op) && op[0] != 'D')
160         {
161             int a,b;
162             scanf("%d%d",&a,&b);
163             if(op[0] == 'Q')
164                 printf("%d\n",Find(a,b));
165             else if(op[0] == 'C')
166                 update(1,id[e[a].x],b);
167         }
168 
169         for(int i=1;i<=N;i++) G[i].clear();
170     }
171 }

 

posted @ 2016-07-14 14:39  Helica  阅读(196)  评论(0编辑  收藏  举报