SPOJ375 Query on a tree(树链剖分)

 

传送门

 

题意

给出一棵树,每条边都有权值,有两种操作:

  • 把第p条边的权值改为x
  • 询问x,y路径上的权值最大的边

code

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #define lson l,m,rt<<1
  5 #define rson m+1,r,rt<<1|1
  6 
  7 using namespace std;
  8 
  9 const int N = 100010;
 10 struct Edge {
 11     int to,nxt,w;
 12 }e[200100];
 13 int head[N],tot,tn,n;
 14 int deth[N],son[N],fa[N],siz[N],bel[N],pos[N];
 15 int mx[N<<2],a[N],b[N],c[N],data[N];
 16 
 17 void init() {
 18     tot = tn = 0;
 19     memset(head,0,sizeof(head));
 20     memset(son,0,sizeof(son));
 21 }
 22 inline void add_edge(int u,int v,int w) {
 23     e[++tot].to = v,e[tot].w = w,e[tot].nxt = head[u],head[u] = tot;
 24 }
 25 void dfs1(int u,int pa) {
 26     siz[u] = 1;
 27     for (int i=head[u]; i; i=e[i].nxt) {
 28         int v = e[i].to;
 29         if (v==pa) continue;
 30         fa[v] = u;
 31         deth[v] = deth[u] + 1;
 32         dfs1(v,u);
 33         siz[u] += siz[v];
 34         if (son[u]==0 || siz[v] > siz[son[u]]) son[u] = v;
 35     }
 36 }
 37 void dfs2(int u,int top) {
 38     pos[u] = ++tn;
 39     bel[u] = top;
 40     if (!son[u]) return ;
 41     dfs2(son[u],top);
 42     for (int i=head[u]; i; i=e[i].nxt) {
 43         int v = e[i].to;
 44         if (v != fa[u] && v != son[u]) dfs2(v,v);
 45     }
 46 }
 47 void pushup(int rt) {
 48     mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
 49 }
 50 void build(int l,int r,int rt) {
 51     if (l==r) {
 52         mx[rt] = data[l];return ;
 53     }
 54     int m = (l + r) >> 1;
 55     build(lson);
 56     build(rson);
 57     pushup(rt);
 58 }
 59 void update(int l,int r,int rt,int p,int x) {
 60     if (l==r) {
 61         mx[rt] = x;return ;
 62     }
 63     int m = (l + r) >> 1;
 64     if (p <= m) update(lson,p,x);
 65     else update(rson,p,x);
 66     pushup(rt);
 67 }
 68 int query(int l,int r,int rt,int L,int R) {
 69     if (L <= l && r <= R) {
 70         return mx[rt]; 
 71     }
 72     int m = (l + r) >> 1;
 73     int ret = -1e9;
 74     if (L <= m) ret = max(ret,query(lson,L,R));
 75     if (R > m)  ret = max(ret,query(rson,L,R));
 76     return ret;
 77 }
 78 void Change(int p,int x) {
 79     if (deth[a[p]] > deth[b[p]]) update(2,n,1,pos[a[p]],x);
 80     else update(2,n,1,pos[b[p]],x);
 81 }
 82 int Ask(int x,int y) {
 83     int ans = -1e9;
 84     while (bel[x] != bel[y]) {
 85         if (deth[bel[x]] < deth[bel[y]]) swap(x,y);
 86         ans = max(ans,query(2,n,1,pos[bel[x]],pos[x]));
 87         x = fa[bel[x]];
 88     }
 89     if (deth[x] > deth[y]) swap(x,y);
 90     if (x != y) ans = max(ans,query(2,n,1,pos[x]+1,pos[y]));
 91     return ans;
 92 }
 93 int main() {
 94     char opt[15];
 95     int T;scanf("%d",&T);
 96     while (T--) {
 97         init();
 98         scanf("%d",&n);
 99         for (int i=1; i<n; ++i) {
100             scanf("%d%d%d",&a[i],&b[i],&c[i]);
101             add_edge(a[i],b[i],c[i]);
102             add_edge(b[i],a[i],c[i]);
103         }
104         deth[1] = 1;
105         dfs1(1,0);
106         dfs2(1,1);
107         for (int i=1; i<n; ++i) {
108             if (deth[a[i]] > deth[b[i]]) data[pos[a[i]]] = c[i]; // 一定是pos 
109             else data[pos[b[i]]] = c[i];
110         }
111         build(2,n,1);
112         scanf("%s",opt);
113         while (opt[0]!='D') {
114             int x,y;
115             scanf("%d%d",&x,&y);
116             if (opt[0]=='Q') printf("%d\n",Ask(x,y));
117             else Change(x,y);
118             scanf("%s",opt);
119         }
120     }
121     return 0;
122 } 

 

posted @ 2017-12-26 21:38  MJT12044  阅读(141)  评论(0编辑  收藏  举报