标签:
题目链接:http://poj.org/problem?id=2763
题意:
给出n个节点的一棵树,树上每个边表示走过这条边需要的时间 。有q个询问,人初始在s点。
有两种操作:
1. 0 u 表示人从当前点走到u点。 此时输出本次移动需要的时间。
2. 1 i w 表示把第i条路的权值变为w。
思路:
权值在边上的树链剖分+线段树单点更新+线段树成段询问
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstring> 5 #include <vector> 6 #include <algorithm> 7 using namespace std; 8 #define maxn 100010 9 #define lson l, m, rt<<1 10 #define rson m+1, r, rt<<1|1 11 int n, q, s, tot; 12 struct Node 13 { 14 int to, next; 15 Node(int t, int n) 16 { 17 to = t; next = n; 18 } 19 Node(){} 20 }mp[maxn<<2]; 21 //vector <Node> mp[maxn]; //不能用vector建图 22 int head[maxn]; 23 void AddEdge(int x, int y) 24 { 25 mp[tot].to = y; 26 mp[tot].next = head[x]; 27 head[x] = tot++; 28 } 29 struct Edge 30 { 31 int from, to, val; 32 }e[maxn]; 33 int pos; 34 int siz[maxn], dep[maxn], top[maxn], fa[maxn], son[maxn], w[maxn], fw[maxn]; 35 long long cnt[maxn<<2]; 36 void PushUp(int rt) 37 { 38 cnt[rt] = cnt[rt<<1] + cnt[rt<<1|1]; 39 } 40 void build(int l, int r, int rt) 41 { 42 cnt[rt] = 0; 43 if(l == r) return; 44 int m = (l+r)>>1; 45 build(lson); 46 build(rson); 47 PushUp(rt); 48 } 49 void update(int p, int val, int l, int r, int rt) 50 { 51 if(l == r) 52 { 53 cnt[rt] = val; return; 54 } 55 int m = (l+r)>>1; 56 if(p <= m) update(p, val, lson); 57 else update(p, val, rson); 58 PushUp(rt); 59 } 60 long long query(int L, int R, int l, int r, int rt) 61 { 62 if(L <= l && R >= r) 63 { 64 return cnt[rt]; 65 } 66 long long ret = 0; 67 int m = (l+r)>>1; 68 if(L <= m) ret += query(L, R, lson); 69 if(R > m) ret += query(L, R, rson); 70 return ret; 71 } 72 int dfs1(int u, int pre, int deep) 73 { 74 siz[u] = 1; fa[u] = pre; dep[u] = deep; 75 int mmax = 0; 76 // for(int i = 0; i < mp[u].size(); i++) 77 for(int i = head[u]; i != -1; i = mp[i].next) 78 { 79 // if(mp[u][i].to != pre) 80 if(mp[i].to != pre) 81 { 82 int temp = dfs1(mp[i].to, u, deep+1); 83 siz[u] += temp; 84 if(son[u] == -1 || temp >= mmax) son[u] = mp[i].to; 85 } 86 } 87 return siz[u]; 88 } 89 void dfs2(int u, int val) 90 { 91 top[u] = val; 92 if(son[u] != -1) 93 { 94 w[u] = pos++; 95 fw[w[u]] = u; 96 dfs2(son[u], val); 97 } 98 else if(son[u] == -1) 99 { 100 w[u] = pos++; 101 fw[w[u]] = u; 102 return; 103 } 104 // for(int i = 0; i < mp[u].size(); i++) 105 for(int i = head[u]; i != -1; i = mp[i].next) 106 { 107 //if(mp[u][i].to != fa[u] && mp[u][i].to != son[u]) dfs2(mp[u][i].to, mp[u][i].to); 108 if(mp[i].to != fa[u] && mp[i].to != son[u]) dfs2(mp[i].to, mp[i].to); 109 } 110 } 111 long long find(int u, int v) 112 { 113 int f1 = top[u], f2 = top[v]; 114 long long temp = 0; 115 while(f1 != f2) 116 { 117 if(dep[f1] < dep[f2]) 118 { 119 swap(f1, f2); 120 swap(u, v); 121 } 122 temp += query(w[f1], w[u], 1, pos-1, 1); 123 u = fa[f1]; f1 = top[u]; 124 } 125 if(u == v) return temp; 126 if(dep[u] > dep[v]) swap(u, v); 127 temp += query(w[son[u]], w[v], 1, pos-1, 1); 128 return temp; 129 } 130 int main() 131 { 132 //freopen("in.txt", "r", stdin); 133 //freopen("out.txt", "w", stdout); 134 while(~scanf("%d%d%d", &n, &q, &s)) 135 { 136 // for(int i = 1; i <= n; i++) mp[i].clear(); 137 pos = 0; tot = 0; memset(son, -1, sizeof(son)); 138 memset(head, -1, sizeof(head)); 139 140 for(int i = 1; i <= n-1; i++) 141 { 142 scanf("%d%d%d", &e[i].from, &e[i].to, &e[i].val); 143 AddEdge(e[i].from, e[i].to); 144 AddEdge(e[i].to, e[i].from); 145 // mp[e[i].from].push_back(Node(e[i].to, e[i].val)); 146 // mp[e[i].to].push_back(Node(e[i].from, e[i].val)); 147 } 148 dfs1(1, -1, 1); 149 dfs2(1, 1); 150 build(1, pos-1, 1); 151 152 for(int i = 1; i <= n-1; i++) 153 { 154 if(dep[e[i].from] > dep[e[i].to]) 155 { 156 swap(e[i].from, e[i].to); 157 } 158 update(w[e[i].to], e[i].val, 1, pos-1, 1); 159 } 160 while(q--) 161 { 162 int op; scanf("%d", &op); 163 if(op == 0) 164 { 165 int u; scanf("%d", &u); 166 printf("%lld\n", find(s, u)); 167 s = u; 168 } 169 else if(op == 1) 170 { 171 int i, ww; scanf("%d%d", &i, &ww); 172 update(w[e[i].to], ww, 1, pos-1, 1); 173 } 174 } 175 } 176 return 0; 177 }
标签:
原文地址:http://www.cnblogs.com/titicia/p/4902402.html