POJ 2763 Housewife Wind(树链剖分(边权))
来源:互联网 发布:萌币捏脸数据 编辑:程序博客网 时间:2024/06/06 03:02
题意:给你一颗树,树边带权,q次询问,两种操作:
0 u : 求从当前位置到u路径的边权和,(下一次操作时起始位置变成了u)
1 i w : 将第i条边的权值改为w
n < 100001 , q < 100001, w < 10000
思路:还是一个裸的树剖,练练写树剖的熟练度。还有这题貌似卡vector?以后安起见都改用前向星写吧。
代码:
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const int maxn = 1e5+5;int fa[maxn], tree[maxn], son[maxn], deep[maxn], num[maxn], top[maxn], edge_id[maxn];ll treeSum[maxn*4];int k, tot, n, q, s, head[maxn];struct node{ int u, v, w, next;}edge[maxn*2], Edge[maxn*2];void init(){ k = tot = 0; memset(head, -1, sizeof(head)); memset(son, 0, sizeof(son)); memset(num, 0, sizeof(num)); memset(treeSum, 0, sizeof(treeSum));}void addEdge(int u, int v, int w){ edge[k].v = v; edge[k].w = w; edge[k].next = head[u]; head[u] = k++;}void dfs1(int u, int pre, int d){ fa[u] = pre; deep[u] = d; num[u] = 1; for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].v; if(v == pre) continue; dfs1(v, u, d+1); num[u] += num[v]; if(!son[u] || num[v] > num[son[u]]) son[u] = v; }}void dfs2(int u, int tp){ tree[u] = tot++; top[u] = tp; if(!son[u]) return ; dfs2(son[u], tp); for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].v; if(v != fa[u] && v != son[u]) dfs2(v, v); }}void pushup(int root){ treeSum[root] = treeSum[root*2]+treeSum[root*2+1];}void update(int root, int l, int r, int pos, int val){ if(l == r) { treeSum[root] = val; return ; } int mid = (l+r)/2; if(pos <= mid) update(root*2, l, mid, pos, val); else update(root*2+1, mid+1, r, pos, val); pushup(root);}ll query(int root, int l, int r, int i, int j){ if(i <= l && j >= r) return treeSum[root]; ll res = 0; int mid = (l+r)/2; if(i <= mid) res += query(root*2, l, mid, i, j); if(j > mid) res += query(root*2+1, mid+1, r, i, j); return res;}ll cal(int u, int v){ int f1 = top[u], f2= top[v]; ll res = 0; while(f1 != f2) { if(deep[f1] < deep[f2]) swap(f1, f2), swap(u, v); res += query(1, 1, n, tree[f1], tree[u]); u = fa[f1]; f1 = top[u]; } if(u == v) return res; if(deep[u] > deep[v]) swap(u, v); res += query(1, 1, n, tree[son[u]], tree[v]); return res;}int main(void){ while(~scanf("%d%d%d", &n, &q, &s)) { init(); for(int i = 1; i < n; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); addEdge(u, v, w); addEdge(v, u, w); Edge[i] = node{u, v, w}; } dfs1(1, 0, 1); dfs2(1, 1); for(int i = 1; i < n; i++) { if(deep[Edge[i].u] > deep[Edge[i].v]) edge_id[i] = Edge[i].u; else edge_id[i] = Edge[i].v; } for(int i = 1; i < n; i++) update(1, 1, n, tree[edge_id[i]], Edge[i].w); while(q--) { int cmd, x, y; scanf("%d%d", &cmd, &x); if(cmd == 0) { printf("%lld\n", cal(s, x)); s = x; } else { scanf("%d", &y); update(1, 1, n, tree[edge_id[x]], y); } } } return 0;}
阅读全文
1 0
- POJ 2763 Housewife Wind(树链剖分(边权))
- 【树链剖分】 POJ 2763 Housewife Wind 边权
- POJ 2763 Housewife Wind 树链剖分 边权
- poj 2763 Housewife Wind(树链剖分,边权)
- poj 2763 Housewife Wind(树链剖分,边权)
- POJ 2763 Housewife Wind (树链剖分)
- POJ 2763 Housewife Wind(树链剖分+BIT)
- 树链剖分(Housewife Wind,POJ 2763)
- poj 2763 Housewife Wind(树链剖分)
- POJ 2763 Housewife Wind 树链剖分
- POJ 2763 Housewife Wind 树链剖分
- poj 2763 Housewife Wind(树链剖分)
- poj 2763 Housewife Wind 树链剖分
- POJ 2763 Housewife Wind (树链剖分)
- POJ 2763 Housewife Wind 树链剖分
- POJ 2763 Housewife Wind(树链剖分)
- poj 2763 Housewife Wind 树链剖分
- POJ 2763Housewife Wind 树链剖分
- 闲聊软件测试自动化(3): 我们期望什么样的测试自动化?
- maven出现 invalid LOC header (bad signature)的解决办法
- 矩阵快速幂与快速幂模板 整理
- Java的反射机制
- STM32的DAC+DMA双通道输出汉字,在示波器中显示汉字
- POJ 2763 Housewife Wind(树链剖分(边权))
- 激活函数
- 判断是否是微信浏览器
- Linux一些最基本命令
- 方唯上传程序后不能登录后台
- BinaryTree的构建和遍历,以及搜索删除(非完全二叉树,非平衡二叉树)
- Weblogic基本介绍、安装以及myeclipse的配置
- 闲聊软件测试自动化(4):我们怎样实现期望的测试自动化?
- Centos 6.X 安装Apache