POJ 2763:Housewife Wind(树链剖分)
http://poj.org/problem?id=2763
题意:给出 n 个点, n-1 条带权边, 询问是询问 s 到 v 的权值, 修改是修改存储时候的第 i 条边的权值。
思路:树链剖分之修改边权。边权的修改, 与点权修改不同的地方在于, 线段树中存的点是边,其中每条边边是以 儿子 的时间戳来记录的。例如: u -> v , dep[u] < dep[v], 说明 u 是 v 的父亲,所以这条边在线段树中的编号就是以 tid[v].
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
#define N 100005
#define INF 0x3f3f3f3f
#define lson rt<<1, l, m
#define rson rt<<1|1, m+1, r
struct node
{
int v, w, next;
}edge[N*];
int head[N], tot;
int time, tid[N], fa[N], rak[N], son[N], dep[N], size[N], top[N];
int tree[N<<];
int e[N][]; /*
树链剖分: 边权的修改, 与点权修改不同的地方在于, 线段树中存的点是边,
其中每条边边是以 儿子 的时间戳来记录的
例如: u -> v , dep[u] < dep[v], 说明 u 是 v 的父亲,
所以这条边在线段树中的编号就是以 tid[v] 的形式来存储.
*/ void init()
{
memset(head, -, sizeof(head));
memset(son, -, sizeof(son));
memset(fa, , sizeof(fa));
time = tot = ;
} void add(int u, int v, int w)
{
edge[tot].next = head[u]; edge[tot].v = v; edge[tot].w = w; head[u] = tot++;
} void dfs1(int u, int f, int d)
{
size[u] = ;
dep[u] = d;
fa[u] = f;
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v;
if(v == f) continue;
dfs1(v, u, d + );
size[u] += size[v];
if(son[u] == - || size[son[u]] < size[v])
son[u] = v;
}
} void dfs2(int u, int f)
{
tid[u] = ++time;
top[u] = f;
rak[time] = u;
if(son[u] == -) return ;
dfs2(son[u], f);
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v;
if(v != son[u] && v != fa[u]) {
dfs2(v, v);
}
}
} void build(int rt, int l, int r)
{
tree[rt] = ;
if(l == r) return ;
int m = (l + r) >> ;
build(lson); build(rson);
} void pushup(int rt)
{
tree[rt] = tree[rt<<] + tree[rt<<|];
} void update(int rt, int l, int r, int id, int w)
{
if(l == id && r == id) {
tree[rt] = w;
return ;
}
if(l == r) return ;
int m = (l + r) >> ;
if(id <= m) update(lson, id, w);
else update(rson, id, w);
pushup(rt);
} long long query(int rt, int l, int r, int L, int R)
{
long long ans = ;
if(L <= l && r <= R) {
ans += tree[rt];
return ans;
}
int m = (l + r) >> ;
if(L <= m) ans += query(lson, L, R);
if(m < R) ans += query(rson, L, R);
return ans;
} long long change(int u, int v)
{
long long ans = ;
int tp1 = top[u], tp2 = top[v];
while(top[u] != top[v]) {
if(dep[top[u]] < dep[top[v]]) swap(u, v);
ans += query(, , time, tid[top[u]], tid[u]);
u = fa[top[u]];
}
if(dep[u] > dep[v]) swap(u, v);
if(u == v) return ans; // 如果是同一个点, 就不能继续询问了
ans += query(, , time, tid[son[u]], tid[v]);
return ans;
} int main()
{
int n, q, s;
scanf("%d%d%d", &n, &q, &s);
init();
for(int i = ; i < n; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
e[i][] = u, e[i][] = v, e[i][] = w;
add(u, v, w); add(v, u, w);
}
dfs1(s, s, );
dfs2(s, s);
build(, , time);
for(int i = ; i < n; i++) {
if(dep[e[i][]] > dep[e[i][]]) swap(e[i][], e[i][]);
update(, , time, tid[e[i][]], e[i][]);
}
for(int i = ; i < q; i++) {
int o, a, b;
scanf("%d", &o);
if(o == ) {
scanf("%d%d", &a, &b);
update(, , time, tid[e[a][]], b);
} else {
scanf("%d", &a);
long long ans = change(s, a);
s = a;
printf("%lld\n", ans);
}
}
return ;
} /*
4 4 1
1 2 1
2 3 2
1 4 1
0 2
1 2 3
0 3
0 4
*/
POJ 2763:Housewife Wind(树链剖分)的更多相关文章
- POJ - 2763 Housewife Wind (树链剖分/ LCA+RMQ+树状数组)
题意:有一棵树,每条边给定初始权值.一个人从s点出发.支持两种操作:修改一条边的权值:求从当前位置到点u的最短路径. 分析:就是在边可以修改的情况下求树上最短路.如果不带修改的话,用RMQ预处理LCA ...
- POJ 2763 Housewife Wind (树链剖分 有修改单边权)
题目链接:http://poj.org/problem?id=2763 n个节点的树上知道了每条边权,然后有两种操作:0操作是输出 当前节点到 x节点的最短距离,并移动到 x 节点位置:1操作是第i条 ...
- poj 2763 Housewife Wind : 树链剖分维护边 O(nlogn)建树 O((logn)²)修改与查询
/** problem: http://poj.org/problem?id=2763 **/ #include<stdio.h> #include<stdlib.h> #in ...
- poj 2763 Housewife Wind(树链拆分)
id=2763" target="_blank" style="">题目链接:poj 2763 Housewife Wind 题目大意:给定一棵 ...
- POJ 2763 Housewife Wind 树链拋分
一.前言 这破题WA了一天,最后重构还是WA,最后通过POJ讨论版得到的数据显示,我看上去是把某个变量写错了..于是,还是低级错误背锅啊....代码能力有待进一步提升2333333 二.题意 某家庭主 ...
- POJ2763 Housewife Wind 树链剖分 边权
POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...
- poj 2763(RMQ+BIT\树链剖分)
传送门:Problem 2763 https://www.cnblogs.com/violet-acmer/p/9686774.html 题意: 一对夫妇居住在xx村庄,小屋之间有双向可达的道路,不会 ...
- POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )
POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...
- POJ 2763 Housewife Wind LCA转RMQ+时间戳+线段树成段更新
题目来源:POJ 2763 Housewife Wind 题意:给你一棵树 2种操作0 x 求当前点到x的最短路 然后当前的位置为x; 1 i x 将第i条边的权值置为x 思路:树上两点u, v距离为 ...
- poj 2763 Housewife Wind (树链剖分)
题目链接:http://poj.org/problem?id=2763 题意: 给定一棵含n个结点的树和树的边权,共有q次操作,分为两种 0 c :求从位置s到c的距离,然后s变成c 1 a b:把第 ...
随机推荐
- ON_NOTIFY_REFLECT : Message Reflection for Windows Controls
转自: https://msdn.microsoft.com/en-us/library/eeah46xd.aspx TN062: Message Reflection for Windows Con ...
- HTML页面刷新、跳转
HTML方式 1.页面刷新 <!-- 5秒之后,跳转到http://www.qunar.com页面 --> <meta http-equiv="refresh" ...
- Java Collections的排序之二
package test.list; import java.util.ArrayList; import java.util.Collections; import java.util.HashSe ...
- TOMCAT 关闭报错:Tomcat did not stop in time. PID file was not removed
关闭tomcat的时候,报出如下错误信息: # ./shutdown.sh Using CATALINA_BASE: /opt/openkm-6.3.1-community/tomcat Using ...
- mysql 常见的几个错误问题
Mysql常见的几个错误问题及解决方法: 1.问题: mysql DNS反解:skip-name-resolve 错误日志有类似警告: 点击(此处)折叠或打开 120119 16:26:04 [War ...
- tableview的cell点击和取消
#pragma mark - 选择cell: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPa ...
- Effective C++ 1.让自己习惯C++
//条款01:视C++为一个语言联邦 // 1:C++主要包含的语言为: // A:C.说到底C++仍然以C为基础.区块(blocks).语句.预处理器.内置数据类型.数组.指针等均来自于C.许多时候 ...
- String类型方法
String类型 //1.返回长度 length var a="lynn_hello"; console.log(a.length); //2.相加 concat() 返回一个新的 ...
- !!常见的上穿突破M20方式——突破还是试探的判断
1和2相似之处在于M5<M20, 最大的区别是M20和M5之间的间距在放大还是缩小,如果是放大,大盘会先试探一下.如果越缩越小,大盘必须选择方向 但是必须注意的是,即使是夹角缩小,选在方向不一定 ...
- 转:JAVA强制类型转换
object对象转换为String的一些总结 ----------------------------------------------------------------------------- ...