POJ 2763 Housewife Wind (树链剖分 有修改单边权)
题目链接: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 (树链剖分 有修改单边权)的更多相关文章
- POJ - 2763 Housewife Wind (树链剖分/ LCA+RMQ+树状数组)
题意:有一棵树,每条边给定初始权值.一个人从s点出发.支持两种操作:修改一条边的权值:求从当前位置到点u的最短路径. 分析:就是在边可以修改的情况下求树上最短路.如果不带修改的话,用RMQ预处理LCA ...
- 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:把第 ...
随机推荐
- BZOJ2226: [Spoj 5971] LCMSum
题解: 考虑枚举gcd,然后问题转化为求<=n且与n互质的数的和. 这是有公式的f[i]=phi[i]*i/2 然后卡一卡时就可以过了. 代码: #include<cstdio> # ...
- Java知识点:Object类
toString()方法 原始实现: public String toString() { return getClass().getName() + "@" + Integer. ...
- 深入分析 ThreadLocal 内存泄漏问题
前言 ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度.但是如果滥用ThreadLocal,就可能 ...
- html5客户端跨域访问php服务端数据
客户端代码: var param = $.param( { feed:JSON.stringify({ content:'abcd' }) } ); $http({ url: 'http://61.1 ...
- LeetCode Invert Binary Tree 反转二叉树
思路:递归解决,在返回root前保证该点的两个孩子已经互换了.注意可能给一个Null. C++ /** * Definition for a binary tree node. * struct Tr ...
- 使用mp4v2将H264+AAC合成mp4文件
录制程序要添加新功能:录制CMMB电视节目,我们的板卡发送出来的是RTP流(H264视频和AAC音频),录制程序要做的工作是: (1)接收并解析RTP包,分离出H264和AAC数据流: (2)将H26 ...
- zoj 2095 Divisor Summation
和 hdu 1215 一个意思// 只是我 1坑了 1 时应该为0 #include <iostream> #include <math.h> #include <map ...
- w3c盒子模型与ie盒子模型
盒子模型是css的专有名词,用来描述页面设置中的各种属性,如内容(content).填充(padding).边框(border).边界(margin),由于这些属性拼在一起,与日常生活中的“盒子”很相 ...
- POJ 1160 Post Office
题意:有n个村庄,要在其中m个村庄里建邮局,每个村庄去邮局的代价为当前村庄到最近的一个有邮局村庄的路程,问总最小代价是多少. 解法:dp.dp[i][j]表示在前j个村庄建立i个邮局后的代价,则状态转 ...
- C# 多线程网络爬虫
原文 C#制作多线程处理强化版网络爬虫 上次做了一个帮公司妹子做了爬虫,不是很精致,这次公司项目里要用到,于是有做了一番修改,功能添加了网址图片采集,下载,线程处理界面网址图片下载等. 说说思路:首相 ...