FZU2082
2015-07-06 00:39
183 查看
树链剖分后要处理的是边的权值,而不是点的权值,但是只要边权下放到点,就可以了
如图
View Code
如图
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> #include <iostream> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <string> #include <math.h> using namespace std; #pragma warning(disable:4996) #pragma comment(linker, "/STACK:1024000000,1024000000") typedef long long LL; const int INF = 1<<30; /* 12 1 1 2 1 2 3 1 3 4 1 4 5 1 5 11 1 11 12 1 1 6 1 6 7 1 7 8 1 6 9 1 6 10 1 1 9 10 */ const int N = 50000 + 10; vector<int> g ; int size , son , fa , depth , top , w , num, ra ; LL tree[N*4]; int edge [3]; int h ; void dfs(int u) { size[u] = 1; son[u] = 0; for (int i = 0; i < g[u].size(); ++i) { int v = g[u][i]; if (v != fa[u]) { fa[v] = u; depth[v] = depth[u] + 1; dfs(v); size[u] += size[v]; if (size[v] > size[son[u]]) son[u] = v; } } } void dfs2(int u, int tp) { w[u] = ++num; ra[num] = u; top[u] = tp; if (son[u] != 0) dfs2(son[u], top[u]); for (int i = 0; i < g[u].size(); ++i) { int v = g[u][i]; if (v != fa[u] && v != son[u]) dfs2(v, v); } } void pushUp(int rt) { tree[rt] = tree[rt << 1] + tree[rt << 1 | 1]; } void update(int l, int r, int rt, int pos, int val) { if (l == r) { tree[rt] = val; return; } int mid = (l + r) >> 1; if (pos <= mid) update(l, mid, rt << 1, pos, val); else update(mid + 1, r, rt << 1 | 1, pos, val); pushUp(rt); } LL ans; void query(int l, int r, int rt, int L, int R) { if (L <= l&&R >= r) { ans += tree[rt]; return; } int mid = (l + r) >> 1; if (L <= mid) query(l, mid, rt << 1, L, R); if (R > mid) query(mid + 1, r, rt << 1 | 1, L, R); } int main() { int n, m, a, b, c; while (scanf("%d%d", &n, &m) != EOF) { memset(tree, 0, sizeof(tree)); for (int i = 1; i <= n; ++i) g[i].clear(); num = 0; for (int i = 1; i < n; ++i) { scanf("%d%d%d", &edge[i][0], &edge[i][1], &edge[i][2]); g[edge[i][0]].push_back(edge[i][1]); g[edge[i][1]].push_back(edge[i][0]); } fa[1] = depth[1] = 0; dfs(1); dfs2(1, 1); for (int i = 1; i < n; ++i) { if (depth[edge[i][0]] > depth[edge[i][1]]) swap(edge[i][0], edge[i][1]); h[edge[i][1]] = edge[i][2]; update(1, n, 1, w[edge[i][1]], edge[i][2]); } while (m--) { scanf("%d%d%d", &a, &b, &c); if (a == 0) { if (depth[edge[b][0]] > depth[edge[b][1]]) swap(edge[b][0], edge[b][1]); update(1, n, 1, w[edge[b][1]], c); h[edge[b][1]] = c; } else { ans = 0; while (top[b] != top[c]) { if (depth[top[b]] < depth[top[c]]) swap(b, c); query(1, n, 1, w[top[b]], w[b]); b = fa[top[b]]; } //b和c一定是在一条链上 if (depth[b]>depth[c]) swap(b, c); //如果b有父亲,那么就有边下放到它,多加了这个点,要减去 query(1, n, 1, w[b], w[c]); if (fa[b] != 0) ans -= h[b]; /* 如果b,c是在一条重链上, 那么询问w[son[b]] 到w[c] 那么就没有加到点b 否则,b,c就是指向同一点,那么w[son[b]] > w[c] , 询问是不会增加任何值的 query(1, n, 1, w[son[b]], w[c]); */ printf("%lld\n", ans); } } } return 0; }
View Code
相关文章推荐
- display:none | visibility:hidden 的区别
- MyBatis入门
- linux 启动oracle报cannot restore segment prot after reloc: Permission denied
- 如何监控Tomcat服务器
- 跟着实例学习设计模式(1)-单例模式(创建型)
- java 时间相关的类互相转换
- 在visual studio 2013中编译Lua5.3.1
- volatile的使用
- C++调用JS,可变参模板实现,方便调用(cocos2d-x)
- Android Framework应用框架层和HAL硬件抽象层以及Linux Kernel底层之间的关系
- OOP in JS - Inheritance
- [学习笔记—Objective-C]《Objective-C 程序设计 第6版》第十章 变量和数据类型
- 简单的NHibernate学习笔记
- Vim技巧之四大模式_普通模式
- 动态页面静态化的实现
- 用react native 做的一个推酷客户端
- 论公司间的开发合作
- windows 2003建立RAID-0 RAID0-1 RAID-5 卷。(vmware环境)
- 第一帖,发个网页版的别踩白块
- 不用任何math方法,实现四舍五入(新浪微博面试题)