码迷,mamicode.com
首页 > 其他好文 > 详细

LightOJ 1348 Aladdin and the Return Journey

时间:2015-10-22 20:51:59      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:

题意:

给出N个节点的一棵树,每个节点有一个权值。

有两种操作:

1)      0 i j, 问节点i->节点j的路上的总权值。

2)      1 i v, 把节点i的权值改变成v。

 

思路:

权值在点上的树链剖分+线段树单点更新+线段树成段询问

  1 #include <iostream>
  2 #include <cstring>
  3 #include <string>
  4 #include <cstdio>
  5 #include <vector>
  6 using namespace std;
  7 int n, q;
  8 #define maxn 30010
  9 #define lson l, m, rt<<1
 10 #define rson m+1, r, rt<<1|1
 11 int siz[maxn], top[maxn], fa[maxn], son[maxn], dep[maxn];
 12 int w[maxn], fw[maxn];
 13 int A[maxn];
 14 vector <int> mp[maxn];
 15 int pos;
 16 int sum[maxn<<2];
 17 void PushUp(int rt)
 18 {
 19     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
 20 }
 21 void build(int l, int r, int rt)
 22 {
 23     sum[rt] = 0;
 24     if(l == r)
 25     {
 26         sum[rt] = A[fw[l]];
 27         return;
 28     }
 29     int m = (l+r)>>1;
 30     build(lson);
 31     build(rson);
 32     PushUp(rt);
 33 }
 34 void update(int p, int val, int l, int r, int rt)
 35 {
 36     if(l == r)
 37     {
 38         sum[rt] = val;
 39         return;
 40     }
 41     int m = (l+r)>>1;
 42     if(p <= m) update(p, val, lson);
 43     else update(p, val, rson);
 44     PushUp(rt);
 45 }
 46 int query_sum(int L, int R, int l, int r, int rt)
 47 {
 48     if(L <= l && R >= r)
 49     {
 50         return sum[rt];
 51     }
 52     int m = (l+r)>>1;
 53     int ret = 0;
 54     if(L <= m) ret += query_sum(L, R, lson);
 55     if(R > m) ret += query_sum(L, R, rson);
 56     return ret;
 57 }
 58 int dfs1(int u, int pre, int deep)
 59 {
 60     siz[u] = 1; dep[u] = deep; fa[u] = pre;
 61     int mmax = 0;
 62     for(int i = 0; i < mp[u].size(); i++)
 63     {
 64         if(mp[u][i] != pre)
 65         {
 66             int temp = dfs1(mp[u][i], u, deep+1);
 67             siz[u] += temp;
 68             if(son[u] == -1 || temp >= mmax) 
 69             {
 70                 son[u] = mp[u][i];
 71                 mmax = temp;
 72             }
 73         }
 74     }
 75     return siz[u];
 76 }
 77 void dfs2(int u, int val)
 78 {
 79     top[u] = val;
 80     if(son[u] != -1)
 81     {
 82         w[u] = ++pos;
 83         fw[w[u]] = u;
 84         dfs2(son[u], val);
 85     }
 86     else if(son[u] == -1)
 87     {
 88         w[u] = ++pos;
 89         fw[w[u]] = u;
 90         return;
 91     }
 92     for(int i = 0; i < mp[u].size(); i++)
 93     {        
 94         if(mp[u][i] != son[u] && mp[u][i] != fa[u]) dfs2(mp[u][i], mp[u][i]);
 95     }
 96 }
 97 int find_sum(int u, int v)
 98 {
 99     int f1 = top[u], f2 = top[v];
100     int temp = 0;
101     while(f1 != f2)
102     {
103         if(dep[f1] < dep[f2])
104         {
105             swap(f1, f2); 
106             swap(u, v);
107         }
108         temp += query_sum(w[f1], w[u], 1, pos, 1);
109         u = fa[f1]; f1 = top[u];
110     }
111     if(dep[u] > dep[v]) swap(u, v);
112     temp += query_sum(w[u], w[v], 1, pos, 1);
113     return temp;
114 }
115 int main() 
116 {
117   //  freopen("in.txt", "r", stdin);
118     int T;
119     scanf("%d", &T);
120     int cast = 0;
121     while(T--)
122     {
123         scanf("%d", &n);
124         cast++;
125         for(int i = 1; i <= n; i++) mp[i].clear(); 
126         pos = 0;
127         memset(son, -1, sizeof(son));
128         for(int i = 1; i <= n; i++) scanf("%d", &A[i]);
129         for(int i = 1; i <= n-1; i++)
130         {
131             int a, b; scanf("%d%d", &a, &b);
132             a++; b++;
133             mp[a].push_back(b);
134             mp[b].push_back(a);
135         }
136         dfs1(1, -1, 1);
137         dfs2(1, 1);
138         build(1, pos, 1);
139         
140         scanf("%d", &q);
141         int op;
142         printf("Case %d:\n", cast);
143         while(q--)
144         {
145             scanf("%d", &op);
146             int u, v; 
147             scanf("%d%d", &u, &v);
148             if(op == 1) update(w[u+1], v, 1, pos, 1);
149             else if(op == 0) printf("%d\n", find_sum(u+1, v+1));
150         }
151         
152     }
153     return 0;
154 }

 

LightOJ 1348 Aladdin and the Return Journey

标签:

原文地址:http://www.cnblogs.com/titicia/p/4902468.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!