[ZJOI2008]树的统计——树链剖分
本题是一个树链剖分裸题,由于比较菜,老是RE,后来发现是因为使用了全局变量。
/**************************************************************
Problem: 1036
User: MrMorning
Language: C++
Result: Accepted
Time:2868 ms
Memory:7332 kb
****************************************************************/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 30006;
//=====================
vector<int> G[maxn];
vector<int> son[maxn];
int weigh[maxn];
int size[maxn];
int vis[maxn];
int depth[maxn];
int fa[maxn];
int next[maxn];
int top[maxn];
int id[maxn];
void build_tree(int root);
void build(int k, int l, int r);
void dfs(int root, int);
void change(int x, int y);
int querysum(int k, int x, int y);
int querymx(int k, int x, int y);
int path_sum(int u, int v);
int path_max(int u, int v);
void solve();
int p, x;
int n;
int nz = 0;
int value[maxn];
struct dat {
int l, r, sum, mx;
} seg[100005];
//=================
int main() {
// freopen("tree.in", "r", stdin);
// freopen("tree.out", "w", stdout);
scanf("%d", &n);
for (int i = 1; i < n; i++) {
int u, v;
scanf("%d %d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
for (int i = 1; i <= n; i++)
cin >> weigh[i];
solve();
return 0;
}
void build(int k, int l, int r) {
seg[k].l = l;
seg[k].r = r;
if (l == r)
return;
int mid = (l + r) >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
return;
}
void change(int k, int x, int y) {
int l = seg[k].l, r = seg[k].r, mid = (l + r) >> 1;
if (l == r) {
seg[k].sum = seg[k].mx = y;
return;
}
if (x <= mid)
change(k << 1, x, y);
else
change(k << 1 | 1, x, y);
seg[k].sum = seg[k << 1].sum + seg[k << 1 | 1].sum;
seg[k].mx = max(seg[k << 1].mx, seg[k << 1 | 1].mx);
}
void solve() {
build_tree(1);
dfs(1, 1);
build(1, 1, n);
for (int i = 1; i <= n; i++) {
change(1, id[i], weigh[i]);
}
int t;
cin >> t;
while (t--) {
int p, u, v;
char command[10];
scanf("%s", command);
scanf("%d %d", &u, &v);
if (command[1] == 'M')
printf("%d\n", path_max(u, v));
else if (command[1] == 'S')
printf("%d\n", path_sum(u, v));
else
change(1, id[u], v);
}
}
void build_tree(int root) { // dfs1
vector<int>::iterator it;
size[root] = 1;
vis[root] = 1;
int Max = -1;
int ans = -1;
for (it = G[root].begin(); it != G[root].end(); it++)
if (!vis[(*it)]) {
int &v = *it;
depth[v] = depth[root] + 1;
fa[v] = root;
build_tree(v);
size[root] += size[v];
son[root].push_back(v);
if (size[v] > Max) {
Max = size[v];
ans = v;
}
}
next[root] = ans;
}
void dfs(int root, int chain) { // dfs2
id[root] = ++nz;
top[root] = chain;
if (son[root].empty())
return;
dfs(next[root], chain);
std::vector<int>::iterator it;
for (it = son[root].begin(); it != son[root].end(); it++) {
int &v = *it;
if (v != next[root]) {
dfs(v, v);
}
}
return;
}
int query_max(int num, int ql, int qr) {
int L = seg[num].l;
int R = seg[num].r;
int mid = (L + R) >> 1;
if (L == ql && R == qr)
return seg[num].mx;
else if (qr <= mid)
return query_max(num << 1, ql, qr);
else if (ql > mid)
return query_max(num << 1 | 1, ql, qr);
else
return max(query_max(num << 1, ql, mid),
query_max(num << 1 | 1, mid + 1, qr));
}
int query_sum(int num, int ql, int qr) {
int L = seg[num].l;
int R = seg[num].r;
int mid = (L + R) >> 1;
if (L == ql && R == qr)
return seg[num].sum;
else if (qr <= mid)
return query_sum(num << 1, ql, qr);
else if (ql > mid)
return query_sum(num << 1 | 1, ql, qr);
else
return query_sum(num << 1, ql, mid) + query_sum(num << 1 | 1, mid + 1, qr);
}
int path_max(int x, int y) {
int mx = -0x3f3f3f;
while (top[x] != top[y]) {
if (depth[top[x]] < depth[top[y]])
swap(x, y);
mx = max(mx, query_max(1, id[top[x]], id[x]));
x = fa[top[x]];
}
if (id[x] > id[y])
swap(x, y);
mx = max(mx, query_max(1, id[x], id[y]));
return mx;
}
int path_sum(int u, int v) {
int sum = 0;
while (top[u] != top[v]) {
if (depth[top[u]] < depth[top[v]])
swap(u, v);
sum += query_sum(1, id[top[u]], id[u]);
u = fa[top[u]];
}
if (id[u] > id[v])
swap(u, v);
sum += query_sum(1, id[u], id[v]);
return sum;
}
调了一个星期才AC,真是弱啊。
[ZJOI2008]树的统计——树链剖分的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count-树链剖分(点权)(单点更新、路径节点最值、路径求和)模板,超级认真写了注释啊啊啊
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 23015 Solved: 9336[Submit ...
- 树的统计Count---树链剖分
NEFU专项训练十和十一——树链剖分 Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t ...
- BZOJ1036[ZJOI2008]树的统计——树链剖分+线段树
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...
- [luogu P2590 ZJOI2008] 树的统计 (树链剖分)
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- luoguP2590 [ZJOI2008]树的统计(树链剖分)
luogu P2590 [ZJOI2008]树的统计 题目 #include<iostream> #include<cstdlib> #include<cstdio> ...
- 洛谷P2590 [ZJOI2008] 树的统计 [树链剖分]
题目传送门 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t ...
- BZOJ 1036 树的统计-树链剖分
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...
- BZOJ-1036 树的统计Count 链剖线段树(模板)=(树链剖分+线段树)
潇爷昨天刚刚讲完...感觉得还可以...对着模板打了个模板...还是不喜欢用指针.... 1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Lim ...
- bzoj1036 树的统计 树链剖分模板
题意:给出树上任意两点,求路径上的值的和与最大值,带单点修改操作 树链剖分思路: 1.对树进行dfs求出点的深度和父亲节点,然后求出轻重儿子(重儿子就是点最多的那个子树,其余都是轻儿子),用一个son ...
随机推荐
- Linux编译移植Qt4的环境_在OMAPL138平台
Linux编译Qt4的环境_OMAPL138 手里有一块创龙OMAPL138的板子,我要在上面成功移植Qt环境和触摸屏幕,这是我第二次进行Linux的Qt环境移植,发现了很多问题,需要重新整理. 我编 ...
- [CodeChef]RIN(最小割)
Description 有m门课可以在n个学期内学习,第i门课在第j个学期的收益是\(X_{i,j}\),一个学期可以学多门课,有的课之间有依赖关系,即必须先学a再学b,求最大收益.n,m<= ...
- 【文件处理】xml 文件 DOM解析
一.Java解析xml.解析xml四种方法.DOM.SAX.JDOM.DOM4j.XPath 此文针对其中的DOM方法具体展开介绍及代码分析 sax.dom是两种对xml文档进行解析的方法(没有具体实 ...
- 2599: [IOI2011]Race
2599: [IOI2011]Race 链接 分析 被memset卡... 点分治,对于重心,遍历子树,记录一个数组T[i],表示以重心为起点的长度为i的路径中最少的边数是多少.然后先遍历子树,更新答 ...
- Android (shape,gradient)使用总结
设置背景色可以通过在res/drawable里定义一个xml,如下: <?xml version="1.0" encoding="utf-8"?> ...
- 《Cracking the Coding Interview》——第14章:Java——题目5
2014-04-26 19:06 题目:Java中的对象反射机制是什么?有鼠么用? 解法:完全不了解,因为java编程经验太少,完全没用过.查了一些资料后,感觉反射机制是个强大并需要边用边体会的强大工 ...
- js限制文本框只能输入特定字符
限制只能输入数字 // ---------------------------------------------------------------------- // <summary> ...
- [转]JS获取URL传参方法
function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...
- win10系统安装之GHOST还原(转+编辑)
注意*:在以下操作中,你可能需要分区你的原来系统盘,如果是重装的话.现在我们使用SSD固态做系统盘盘,这个分区的话,点选mbr重新引导,以及对齐复选框. 如果前面过程都没问题,在安装过程中出现 ...
- NodeJs03 express框架 Todo商城
前言 由于NodeJs本身的异步非阻塞特性和对http的天然支持,所以使用NodeJs编写高性能,可伸缩的Web服务器非常简单.开发完整的Web服务器还需要路由,错误处理,请求拦截,请求和响应的解析, ...