POJ2763 Housewife Wind 树链剖分 边权

传送门:http://poj.org/problem?id=2763

题意:

n个点的,n-1条边,有边权

修改单边边权

询问 输出 当前节点到 x节点的最短距离,并移动到 x 节点位置

题解:

树链剖分裸题

树链剖分就是将树分割为多条边,然后利用数据结构来维护这些链的一个技巧

  • 重儿子:父亲节点的所有儿子中子树结点数目最多( sizesiz**e 最大)的结点;
  • 轻儿子:父亲节点中除了重儿子以外的儿子;
  • 重边:父亲结点和重儿子连成的边;
  • 轻边:父亲节点和轻儿子连成的边;
  • 重链:由多条重边连接而成的路径;
  • 轻链:由多条轻边连接而成的路径;

1.求出子树大小和每个点的重儿子,处理sz数组,son数组,fa数组和dep数组

2.连接重链,记录dfs序,每个链的顶端节点,处理出rank数组,top数组,id数组

3.维护链上信息

修改边权就查询点的深度大的点,用大的点去存这条边的边权,其余的就和点权的是一样的了

代码:

#include <set>
#include <map>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f; int n, m, Q;
int a[maxn], sz[maxn], dep[maxn], fa[maxn], top[maxn], id[maxn], son[maxn], Rank[maxn];
int sum[maxn << 2], lazy[maxn << 2]; struct EDGE {
int u, v, nt;
} edge[maxn << 1];
int head[maxn], summ, cnt; void add_edge(int u, int v) {
edge[++summ].u = u; edge[summ].v = v; edge[summ].nt = head[u]; head[u] = summ;
} void dfs1(int u) {
sz[u] = 1; son[u] = 0;
for (int i = head[u]; ~i; i = edge[i].nt) {
int v = edge[i].v;
if (v != fa[u]) {
fa[v] = u;
dep[v] = dep[u] + 1;
dfs1(v);
sz[u] += sz[v];
if (sz[v] > sz[son[u]]) son[u] = v;
}
}
} void dfs2(int u, int tp, int x) {
top[u] = tp; id[u] = ++cnt; Rank[cnt] = u;
if (son[u]) dfs2(son[u], tp, 1);
for (int i = head[u]; ~i; i = edge[i].nt) {
int v = edge[i].v;
if (v == son[u] || v == fa[u]) continue;
dfs2(v, v, 2);
}
} void init() {
memset(head, -1, sizeof(head));
summ = 1; cnt = 0;
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= m; i++) {
int u, v;
scanf("%d %d", &u, &v);
add_edge(u, v); add_edge(v, u);
}
dep[1] = 1; fa[1] = 0;
dfs1(1);
dfs2(1, 1, 1);
} void pushup(int rt) {
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
} void pushdown(int rt, int mid) {
if (lazy[rt]) {
lazy[rt << 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
sum[rt << 1] += lazy[rt] * (mid - mid / 2);
sum[rt << 1 | 1] += lazy[rt] * (mid / 2);
lazy[rt] = 0;
}
} void build(int l, int r, int rt) {
lazy[rt] = 0;
if (l == r) {
sum[rt] = a[Rank[l]];
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
pushup(rt);
} void update(int L, int R, int val, int l, int r, int rt) {
if (L <= l && r <= R) {
sum[rt] += val * (r - l + 1);
lazy[rt] += val;
return;
}
pushdown(rt, r - l + 1);
int mid = (l + r) >> 1;
if (L <= mid) update(L, R, val, lson);
if (mid < R) update(L, R, val, rson);
pushup(rt);
} int query(int pos, int l, int r, int rt) {
if (l == r) {
return sum[rt];
}
pushdown(rt, r - l + 1);
int mid = (l + r) >> 1;
if (pos <= mid) return query(pos, lson);
if (mid < pos) return query(pos, rson);
} void change(int x, int y, int val) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) std::swap(x, y);
update(id[top[x]], id[x], val, 1, n, 1);
x = fa[top[x]];
}
if (dep[x] > dep[y]) std::swap(x, y);
update(id[x], id[y], val, 1, n, 1);
} int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
while (~scanf("%d %d %d", &n, &m, &Q)) {
init();
build(1, n, 1);
while (Q--) {
char s[2];
int x, y, z;
scanf("%s", s);
if (s[0] == 'I') {
scanf("%d %d %d", &x, &y, &z);
change(x, y, z);
}
if (s[0] == 'D') {
scanf("%d %d %d", &x, &y, &z);
change(x, y, -z);
}
if (s[0] == 'Q') {
scanf("%d", &x);
printf("%d\n", query(id[x], 1, n, 1));
}
}
}
}

POJ2763 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. BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...

  5. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  6. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  7. HDU3669 Aragorn's Story 树链剖分 点权

    HDU3669 Aragorn's Story 树链剖分 点权 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: n个点的,m条边,每个点都 ...

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

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

  9. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

随机推荐

  1. bzoj1877 晨跑

    Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他 坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个 ...

  2. 2017 校赛 问题 B: CZJ-Superman

    题目描述 “那是只鸟?那是飞机?那是——超人!” 程序员在看完<CZJ-Superman>之后,励志要成为一名“CZJ-Superman”,学会了两个特殊技能ZZZ和JJJ,足以成为一名“ ...

  3. 2014年山东省第五届ACM大学生程序设计竞赛F题:Full Binary Tree

    题目描述 In computer science, a binary tree is a tree data structure in which each node has at most two ...

  4. C++中的union

    1:,像任何类一样,union可以指定保护标记使成员成为公用的.私有的或受保护的.默认情况下,union 表现得像 struct:除非另外指定,否则 union 的成员都为 public 成员. 2: ...

  5. URL的转义和解析

    在开始python编程之前我们先来看看一个关与url的知识 在url中会有一些特殊字符,如果你写过cgi程序,并且提交一个表单去调用你的cgi,你会很清楚的 像?name=aiqier&age ...

  6. html--图片img

    一.图片的基本格式 当前万维网上流行的图像格式以GIF及JPEG为主,另外还有一个PNG.以下做分别介绍: 1.GIF格式:采用LZW压缩,是以压缩相同颜色的色块来减少图像大小的.(LZW压缩是一种能 ...

  7. windows/Linux/Mac下安装maven,maven作用

    Linux下安装maven 1.首先到Maven官网下载安装文件,目前最新版本为3.0.3,下载文件为apache-maven-3.3.9-bin.tar.gz,下载可以使用wget命令: 2.进入下 ...

  8. ES6语法~解构赋值、箭头函数、class类继承及属性方法、map、set、symbol、rest、new.target、 Object.entries...

    2015年6月17日 ECMAScript 6发布正式版本 前面介绍基本语法,  后面为class用法及属性方法.set.symbol.rest等语法. 一.基本语法:  1.         定义变 ...

  9. C#的选择语句练习(一)

    1.请输入一个数x,若x<1,则y=x:若1<=x<10,则y=2x-1:若x>=10,则y=3x-11,要求随意输入一个x值,求出y值. 2.输入问题[你有房子吗?],若回答 ...

  10. POJ 2406 Power Strings next数组循环节应用、

    题意:就给出个字符串做*的定义.a^0 = "" (the empty string) and a^(n+1) = a*(a^n).    题目要求n的最大值. 思路: 化简上面的 ...