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(树链剖分)的更多相关文章

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

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

  2. POJ 2763 Housewife Wind (树链剖分 有修改单边权)

    题目链接:http://poj.org/problem?id=2763 n个节点的树上知道了每条边权,然后有两种操作:0操作是输出 当前节点到 x节点的最短距离,并移动到 x 节点位置:1操作是第i条 ...

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

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

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

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

  5. POJ 2763 Housewife Wind 树链拋分

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

  6. POJ2763 Housewife Wind 树链剖分 边权

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

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

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

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

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

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

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

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

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

随机推荐

  1. Java控制语句——if语句

    Java控制语句分为三大类:①顺序结构:②选择结构:③循环结构. 选择结构又分为:①单选择结构:②双选择结构:③多选择结构. 主要涉及: if_else , switch , while , brea ...

  2. AE设置投影而非重投影IGeoDatasetSchemaEdit

    AE设置投影而非重投影 读取一个jpg格式的影像,包含jgw文件,这时设置投影.赋值操作. IRasterDataset raster = rasterWsp.OpenRasterDataset(Fi ...

  3. Vue.2.0.5-Render 函数

    基础 Vue 推荐使用在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 templa ...

  4. WCF笔记

    http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iparameterinspector.aftercall ...

  5. 学习jsp(1)

    我的开发环境是:jdk1.7;netbean ;tomcat7. 尝试着写了第一个程序: ublic class myServlet extends HttpServlet{    @Override ...

  6. 01分数规划zoj2676(最优比例,最小割集+二分)

    ZOJ Problem Set - 2676         Network Wars Time Limit: 5 Seconds      Memory Limit: 32768 KB      S ...

  7. exjs3.2的gridPanel的表头总宽度与列的总宽度不一致的解决方案

    修复之前的bug问题 修复办法,谷歌浏览器中,table的单元格实际宽度=指定宽度+padding,所以只要重写gridview里的一个方法: Ext.override(Ext.grid.GridVi ...

  8. paper 27 :图像/视觉显著性检测技术发展情况梳理(Saliency Detection、Visual Attention)

    1. 早期C. Koch与S. Ullman的研究工作. 他们提出了非常有影响力的生物启发模型. C. Koch and S. Ullman . Shifts in selective visual ...

  9. 关于VS 中 HttpHandler 的设置 500.23

    前一段时间在讲 HttpHandler 的过程中遇到一些问题,在此分享一下. 使用VS2012 添加HttpHandler后,在web.config配置的节点如下: <?xml version= ...

  10. 安装交叉编译器arm-linux-gcc

    需要交叉编译环境故安装交叉编译环境    1.在宿主机的/usr/local/arm目录存放交叉编译器        mkdir /usr/local/arm    2.解压交叉编译器包至/usr/l ...