[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 ...
随机推荐
- Multiplication Puzzle ZOJ - 1602
Multiplication Puzzle ZOJ - 1602 传送门 The multiplication puzzle is played with a row of cards, each c ...
- python——闰年的判断
写一个程序,判断给定年份是否为闰年. 这样定义闰年的:能被4整除但不能被100整除,或者能被400整除都是闰年. while(1): year = input("请输入一个年份,让我判断一下 ...
- poj1182食物链
Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到 ...
- keil 使用C++编程主要要点
1.中断处理,添加一下宏定义.如果不添加,中断服务函数不会链接到下载文件中:发生中断后,会停留在xxx.s文件的 "B ."语句. #ifdef __cplusplus exter ...
- 6.定制10MINS首页1
原始代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ...
- Android 支付宝H5 没有回调
今天测试反馈问题,说,手机上没有安装支付宝的,调用支付宝支付之后,没有回调.不提示成功也不提示失败. 我自己试了半天也都是没有问题 .后来终于可以试出来了. 发现原来是,清单里面注册的Activity ...
- https refused 解决方法
今天调试Android程序,所有的手机都ok,后来,我一个手机一直说,refused. 其实这就说明代码是没有问题的,你应该可以根据这个把代码的原因排除.然后剩下的,网络请求还能有什么,网路白. 果然 ...
- 《Cracking the Coding Interview》——第5章:位操作——题目5
2014-03-19 06:22 题目:将整数A变成整数B,每次只能变一个二进制位,要变多少次呢. 解法:异或,然后求‘1’的个数. 代码: // 5.5 Determine the number o ...
- [译]12-spring依赖注入
每个java应用程序都是由多个类协作才最终生成了终端用户所使用的系统.当编写复杂java应用程序的时,类之间应尽 可能保持独立,因为这样更容易做到代码的重用,也有利于单元测试的开展.spring的依赖 ...
- 系统编程--高级IO
1.非阻塞I/O 非阻塞I/O使我们可以调用不会永远阻塞的I/O操作,例如open,read和write.如果这种操作不能完成,则立即出错返回,表示该操作如继续执行将继续阻塞下去.对于一个给定的描述符 ...