题目链接:http://poj.org/problem?id=2763

n个节点的树上知道了每条边权,然后有两种操作:0操作是输出 当前节点到 x节点的最短距离,并移动到 x 节点位置;1操作是第i条边的边权变成x。

树链边权剖分的模版题,修改单边权和求和。

 //#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1e5 + ;
struct EDGE {
int next, to, cost;
}edge[MAXN << ];
int head[MAXN], tot;
int from[MAXN], to[MAXN], cost[MAXN];
int par[MAXN], dep[MAXN], son[MAXN], size[MAXN];
int top[MAXN], id[MAXN], cnt; void init() {
cnt = tot = ;
memset(head, -, sizeof(head));
} inline void add(int u, int v, int cost) {
edge[tot].next = head[u];
edge[tot].to = v;
head[u] = tot++;
} void dfs1(int u, int p, int d) {
dep[u] = d, par[u] = p, size[u] = , son[u] = u;
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if(v == p)
continue;
dfs1(v, u, d + );
if(size[v] >= size[son[u]])
son[u] = v;
size[u] += size[v];
}
} void dfs2(int u, int p, int t) {
top[u] = t, id[u] = ++cnt;
if(son[u] != u)
dfs2(son[u], u, t);
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if(v == son[u] || v == p)
continue;
dfs2(v, u, v);
}
} struct segtree {
int l, r, val;
}T[MAXN << ]; void build(int p, int l, int r) {
int mid = (l + r) >> ;
T[p].l = l , T[p].r = r;
if(l == r) {
return ;
}
build(p << , l, mid);
build((p << )|, mid + , r);
} void updata(int p, int pos, int num) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == T[p].r && T[p].l == pos) {
T[p].val = num;
return ;
}
if(pos <= mid) {
updata(p << , pos, num);
}
else {
updata((p << )|, pos, num);
}
T[p].val = T[p << ].val + T[(p << )|].val;
} int query(int p, int l, int r) {
int mid = (T[p].l + T[p].r) >> ;
if(l == T[p].l && T[p].r == r) {
return T[p].val;
}
if(r <= mid) {
return query(p << , l, r);
}
else if(l > mid) {
return query((p << )|, l, r);
}
else {
return query(p << , l, mid) + query((p << )|, mid + , r);
}
} int find(int u, int v) {
int fu = top[u], fv = top[v], res = ;
while(fv != fu) {
if(dep[fu] > dep[fv]) {
res += query(, id[fu], id[u]);
u = par[fu];
fu = top[u];
}
else {
res += query(, id[fv], id[v]);
v = par[fv];
fv = top[v];
}
}
if(v == u)
return res;
else if(dep[u] > dep[v])
return res + query(, id[son[v]], id[u]);
else
return res + query(, id[son[u]], id[v]);
} int main()
{
int n, m, root;
while(~scanf("%d %d %d", &n, &m, &root)) {
init();
for(int i = ; i < n; ++i) {
scanf("%d %d %d", from + i, to + i, cost + i);
add(from[i], to[i], cost[i]);
add(to[i], from[i], cost[i]);
}
dfs1(, , );
dfs2(, , );
build(, , cnt);
for(int i = ; i < n; ++i) {
if(dep[from[i]] < dep[to[i]])
swap(from[i], to[i]);
updata(, id[from[i]], cost[i]);
}
int op, pos, num;
while(m--) {
scanf("%d", &op);
if(op) {
scanf("%d %d", &pos, &num);
updata(, id[from[pos]], num);
}
else {
scanf("%d", &pos);
printf("%d\n", find(root, pos));
root = pos;
}
}
}
}

POJ 2763 Housewife Wind (树链剖分 有修改单边权)的更多相关文章

  1. POJ - 2763 Housewife Wind (树链剖分/ LCA+RMQ+树状数组)

    题意:有一棵树,每条边给定初始权值.一个人从s点出发.支持两种操作:修改一条边的权值:求从当前位置到点u的最短路径. 分析:就是在边可以修改的情况下求树上最短路.如果不带修改的话,用RMQ预处理LCA ...

  2. poj 2763 Housewife Wind : 树链剖分维护边 O(nlogn)建树 O((logn)²)修改与查询

    /** problem: http://poj.org/problem?id=2763 **/ #include<stdio.h> #include<stdlib.h> #in ...

  3. poj 2763 Housewife Wind(树链拆分)

    id=2763" target="_blank" style="">题目链接:poj 2763 Housewife Wind 题目大意:给定一棵 ...

  4. POJ 2763 Housewife Wind 树链拋分

    一.前言 这破题WA了一天,最后重构还是WA,最后通过POJ讨论版得到的数据显示,我看上去是把某个变量写错了..于是,还是低级错误背锅啊....代码能力有待进一步提升2333333 二.题意 某家庭主 ...

  5. POJ2763 Housewife Wind 树链剖分 边权

    POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...

  6. poj 2763(RMQ+BIT\树链剖分)

    传送门:Problem 2763 https://www.cnblogs.com/violet-acmer/p/9686774.html 题意: 一对夫妇居住在xx村庄,小屋之间有双向可达的道路,不会 ...

  7. POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )

    POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...

  8. POJ 2763 Housewife Wind LCA转RMQ+时间戳+线段树成段更新

    题目来源:POJ 2763 Housewife Wind 题意:给你一棵树 2种操作0 x 求当前点到x的最短路 然后当前的位置为x; 1 i x 将第i条边的权值置为x 思路:树上两点u, v距离为 ...

  9. poj 2763 Housewife Wind (树链剖分)

    题目链接:http://poj.org/problem?id=2763 题意: 给定一棵含n个结点的树和树的边权,共有q次操作,分为两种 0 c :求从位置s到c的距离,然后s变成c 1 a b:把第 ...

随机推荐

  1. git push提示或错误

    当 git 和 gerrit 一起使用的时候,你创建了一个 tag,现在需要 push 到远程仓库,当你没有权限的时候,会出现如下提示: $ git push origin v20150203 Tot ...

  2. 前端JS对后台传递的timestamp的转换

    后台传递的timestamp类型的数据的JSON: Date.prototype.format = function(format) { var o = { "M+" : this ...

  3. HNOI2010弹飞绵羊

    不得不说块状数组好神奇的啊!这道题的标签可是splay的启发是合并(什么高大上的东西),竟然这么轻松的就解决了! var x,y,i,j,tot,n,m,ch:longint; f,k,l,bl,go ...

  4. 证明:寝室分配问题是NPC问题

    P.NP.NPC.NP-hard P:多项式时间能够解决的问题的集合,比如最短路径问题是集合P的一个元素,而最短路径问题本身又是一个集合,因此P是集合的集合. NP:多项式时间内能够验证的问题的集合. ...

  5. HDU 2544 最短路 (最短路,spfa)

    题意:中文题目 思路:spfa+SLF优化.关于SPFA的详情请戳我 #include <bits/stdc++.h> using namespace std; , INF=0x7f7f7 ...

  6. Go2Shell 打开设置窗口

    Go2Shell默认没有设置界面,需要用命令行打开 在Shell中输入: open -a Go2Shell --args config

  7. 【转】Linux时间函数之gettimeofday()函数之使用方法

    原文网址:http://blog.csdn.net/tigerjibo/article/details/7039434 一.gettimeofday()函数的使用方法: 1.简介: 在C语言中可以使用 ...

  8. mybatis返回HashMap结果类型与映射

    <!-- 返回HashMap结果 类型--> <!-- 如果想返回JavaBean,只需将resultType设置为JavaBean的别名或全限定名 --> <!-- T ...

  9. hashCode之一--两个对象值相同,有相同的hash code

    两个对象值相同(x.equals(y) == true),则一定有相同的hash code. 这是java语言的定义:  因为:Hash,一般翻译做“散列”,也有直接音译为"哈希" ...

  10. Easy steps to create a System Tray Application with C# z

    Hiding the C# application to the system tray is quiet straight forward. With a few line of codes in ...