poj 2763 Housewife Wind : 树链剖分维护边 O(nlogn)建树 O((logn)²)修改与查询
/**
problem: http://poj.org/problem?id=2763
**/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
using namespace std; const int MAXN = ; template <typename T>
class SegmentTree {
private:
struct Node {
int left, right;
T sum, lazy;
} node[MAXN << ];
T data[MAXN];
void pushUp(int root) {
node[root].sum = node[root << ].sum + node[root << | ].sum;
}
void pushDown(int root) {
if(node[root].left == node[root].right) return;
int lson = root << ;
int rson = root << | ;
node[lson].sum = node[root].lazy * (node[lson].right - node[lson].left + );
node[rson].sum = node[root].lazy * (node[rson].right - node[rson].left + );
node[lson].lazy = node[root].lazy;
node[rson].lazy = node[root].lazy;
node[root].lazy = ;
}
public:
void build(int left, int right, int root = ) {
node[root].left = left;
node[root].right = right;
node[root].lazy = ;
if(left == right) {
node[root].sum = data[left];
} else {
int mid = (left + right) >> ;
build(left, mid, root << );
build(mid + , right, root << | );
pushUp(root);
}
}
void update(int left, int right, T value, int root = ) {
int lson = root << ;
int rson = root << | ;
if(node[root].lazy) pushDown(root);
if(node[root].left == left && node[root].right == right) {
node[root].sum = value * (right - left + );
node[root].lazy = value;
return ;
}
if(left >= node[rson].left) {
update(left, right, value, rson);
} else if(right <= node[lson].right) {
update(left, right, value, lson);
} else {
update(left, node[lson].right, value, lson);
update(node[rson].left, right, value, rson);
}
pushUp(root);
}
T query(int left, int right, int root = ) {
int lson = root << ;
int rson = root << | ;
if(node[root].lazy) pushDown(root);
if(node[root].left == left && node[root].right == right) {
return node[root].sum;
}
if(left >= node[rson].left) {
return query(left, right, rson);
} else if(right <= node[lson].right) {
return query(left, right, lson);
} else {
return query(left, node[lson].right, lson) + query(node[rson].left, right, rson);
}
}
void clear(int n, const vector<int> &d) {
for(int i = ; i <= n; i ++) {
this->data[i] = d[i];
}
build(, n);
}
}; template <typename T>
class TreeToLink {
private:
struct Point {
int size, son, depth, father, top, newId;
T data;
} point[MAXN];
struct Edge {
int to, next;
} edge[MAXN << ];
int oldId[MAXN], first[MAXN], sign, sumOfPoint, cnt;
SegmentTree<T> st;
void dfs1(int u, int father = , int depth = ) {
point[u].depth = depth;
point[u].father = father;
point[u].size = ;
int maxson = -;
for(int i = first[u]; i != -; i = edge[i].next) {
int to = edge[i].to;
if(to == father) continue;
dfs1(to, u, depth + );
point[u].size += point[to].size;
if(point[to].size > maxson) {
point[u].son = to;
maxson = point[to].size;
}
}
}
void dfs2(int u, int top) {
point[u].newId = ++cnt;
oldId[cnt] = u;
point[u].top = top;
if(point[u].son == -) {
return ;
}
dfs2(point[u].son, top);
for(int i = first[u]; i != -; i = edge[i].next) {
int to = edge[i].to;
if(to == point[u].son || to == point[u].father) continue;
dfs2(to, to);
}
}
public:
void clear(int n) {
sumOfPoint = n;
sign = ;
cnt = ;
for(int i = ; i <= n; i ++) {
first[i] = -;
point[i].son = -;
// scanf("%d", &point[i].data); // input
point[i].data = ;
}
}
void addEdgeOneWay(int u, int v) {
edge[sign].to = v;
edge[sign].next = first[u];
first[u] = sign ++;
}
void addEdgeTwoWay(int u, int v) {
addEdgeOneWay(u, v);
addEdgeOneWay(v, u);
}
void preWork(int x = ) {
dfs1(x);
dfs2(x, x);
vector<int> data(sumOfPoint + );
for(int i = ; i <= sumOfPoint; i ++) {
data[i] = point[oldId[i]].data;
}
st.clear(sumOfPoint, data);
}
void updatePath(int x, int y, T z){
while(point[x].top != point[y].top){
if(point[point[x].top].depth < point[point[y].top].depth)
swap(x, y);
st.update(point[point[x].top].newId, point[x].newId, z);
x = point[point[x].top].father;
}
if(point[x].depth > point[y].depth)
swap(x, y);
st.update(point[x].newId, point[y].newId, z);
}
T queryPath(int x, int y){
T ans = ;
while(point[x].top != point[y].top){
if(point[point[x].top].depth < point[point[y].top].depth)
swap(x, y);
ans += st.query(point[point[x].top].newId, point[x].newId);
x = point[point[x].top].father;
}
if(x == y) return ans; // Edge
if(point[x].depth > point[y].depth)
swap(x, y);
// ans += st.query(point[x].newId, point[y].newId); // Point
ans += st.query(point[point[x].son].newId, point[y].newId); // Edge
return ans;
}
void updateSon(int x, T z){
st.update(point[x].newId, point[x].newId + point[x].size - , z);
}
T querySon(int x){
return st.query(point[x].newId, point[x].newId + point[x].size - );
}
T queryPoint(int x) {
return queryPath(x, x);
}
void updatePoint(int x, T z) {
updatePath(x, x, z);
}
bool deeper(int u, int v){
return point[u].depth > point[v].depth;
}
}; class Solution {
private:
int n, q, s;
TreeToLink<int> ttl;
struct Edge{
int u, v, w;
}edge[MAXN];
public:
void solve() {
scanf("%d%d%d", &n, &q, &s);
ttl.clear(n);
for(int i = ; i < n; i ++){
scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
ttl.addEdgeTwoWay(edge[i].u, edge[i].v);
}
ttl.preWork(s);
for(int i = ; i < n; i ++){
if(ttl.deeper(edge[i].u, edge[i].v)){
swap(edge[i].u, edge[i].v);
}
ttl.updatePoint(edge[i].v, edge[i].w);
}
int now = s;
for(int i = , a, b, c; i < q; i ++){
scanf("%d%d", &a, &b);
if(a == ){
scanf("%d", &c);
ttl.updatePoint(edge[b].v, c);
}else{
printf("%d\n", ttl.queryPath(now, b));
now = b;
}
}
}
} DarkScoCu; int main() {
DarkScoCu.solve();
return ;
}
poj 2763 Housewife Wind : 树链剖分维护边 O(nlogn)建树 O((logn)²)修改与查询的更多相关文章
- 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(树链拆分)
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村庄,小屋之间有双向可达的道路,不会 ...
- hdu 3966 Aragorn's Story : 树链剖分 O(nlogn)建树 O((logn)²)修改与查询
/** problem: http://acm.hdu.edu.cn/showproblem.php?pid=3966 裸板 **/ #include<stdio.h> #include& ...
- 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距离为 ...
随机推荐
- 关于C#的Lock锁思考
大家都知道多线程并发时候存在一个线程同步的问题,一般使用lock关键字来处理. lock关键字的结果如下: object locker=new object(); lock(locker) { ... ...
- 数据分析核心包——pandas
一.pandas简介 pandas是一个强大的Python数据分析的工具包,是基于NumPy构建的. 1.pandas的主要功能 (1)具备对其功能的数据结构DataFrame.Series (2)集 ...
- Form表单元素
Form表单元素 action method input: name value type: text password button radio checkbox file submit reset ...
- javascript实现数据结构:稀疏矩阵的十字链表存储表示
当矩阵的非零个数和位置在操作过程中变化大时,就不宜采用顺序存储结构来表示三元组的线性表.例如,在作“将矩阵B加到矩阵A上”的操作时,由于非零元的插入或删除将会引起A.data中元素的移动.为此,对这种 ...
- AMP+EPP3.0的开发环境配置
经过摸索,总结出下列Apache.MySQL.PHP.EPP.ZendDebugger的开发环境配置方法: 版本: Apache: Apache-httpd-2.2.25-win32-x86-no_s ...
- js:JavaScript中的ActiveXObject对象
JavaScript中的ActiveXObject对象作用: https://blog.csdn.net/pl1612127/article/details/77862174
- day013-流
1. 常用函数式接口 1.1 Predicate接口 有时候我们需要对某种的数据进行判断,从而得到一个boolean值结果.这时可以使用java.util.function.Predicate< ...
- Master HA彻底解密
本课主题 Master HA 解析 Master HA 解析源码分享 Master HA 解析 生产环境下一般采用 ZooKeeper 做 HA,且建义为 3台 Master, ZooKeeper 会 ...
- 建立virtualenv环境
建立virtualenv环境 virtualenv --no-site-packages yourenv 其中,yourenv是给环境起的名称 --no-site-packages表示安装的pytho ...
- 描边时消除锯齿SetSmoothingMode
SmoothingModeAntiAlias 指定消除锯齿的呈现. SmoothingModeDefault 指定默认模式. SmoothingModeHighQuality 指定高质量.低速度呈现. ...