_bzoj1036 [ZJOI2008]树的统计Count【树链剖分】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1036
保存模版。
执行qmax与qsum操作,往上爬的时候最开始的代码出了点小问题,往上爬的点应该是dep[top[u]]更深的点,而不是dep[u]更深的点。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm> const int maxn = 30005; int n, q, t1, t2, root;
int head[maxn], to[maxn << 1], next[maxn << 1], lb, cnt;
int siz[maxn], dep[maxn], fa[maxn], id[maxn], heavy[maxn], v[maxn], top[maxn], a[maxn];
char opr[10];
struct Node {
int ql, qr, mx, sm;
} tree[maxn << 2]; inline void ist(int aa, int ss) {
to[lb] = ss;
next[lb] = head[aa];
head[aa] = lb;
++lb;
}
void dfs1(int r) {
siz[r] = 1;
dep[r] = dep[fa[r]] + 1;
int mx = 0, id = 0;
for (int j = head[r]; j != -1; j = next[j]) {
if (to[j] != fa[r]) {
fa[to[j]] = r;
dfs1(to[j]);
siz[r] += siz[to[j]];
if (siz[to[j]] > mx) {
mx = siz[id = to[j]];
}
}
}
heavy[r] = id;
}
void dfs2(int r, int tp) {
if (!r) {
return;
}
top[r] = tp;
id[r] = ++cnt;
a[cnt] = v[r];
dfs2(heavy[r], tp);
for (int j = head[r]; j != -1; j = next[j]) {
if (to[j] != fa[r] && to[j] != heavy[r]) {
dfs2(to[j], to[j]);
}
}
}
void make_tree(int p, int left, int right) {
tree[p].ql = left;
tree[p].qr = right;
if (left == right) {
tree[p].mx = tree[p].sm = a[left];
return;
}
int mid = (left + right) >> 1;
make_tree(p << 1, left, mid);
make_tree(p << 1 | 1, mid + 1, right);
tree[p].mx = std::max(tree[p << 1].mx, tree[p << 1 | 1].mx);
tree[p].sm = tree[p << 1].sm + tree[p << 1 | 1].sm;
}
void upd(int p, int r, int value) {
if (tree[p].ql == tree[p].qr) {
tree[p].mx = tree[p].sm = value;
return;
}
int mid = (tree[p].ql + tree[p].qr) >> 1;
if (r <= mid) {
upd(p << 1, r, value);
}
else {
upd(p << 1 | 1, r, value);
}
tree[p].mx = std::max(tree[p << 1].mx, tree[p << 1 | 1].mx);
tree[p].sm = tree[p << 1].sm + tree[p << 1 | 1].sm;
}
int getmax(int p, int left, int right) {
if (tree[p].ql == left && tree[p].qr == right) {
return tree[p].mx;
}
int mid = (tree[p].ql + tree[p].qr) >> 1;
if (right <= mid) {
return getmax(p << 1, left, right);
}
if (left > mid) {
return getmax(p << 1 | 1, left, right);
}
return std::max(getmax(p << 1, left, mid), getmax(p << 1 | 1, mid + 1, right));
}
int getsum(int p, int left, int right) {
if (tree[p].ql == left && tree[p].qr == right) {
return tree[p].sm;
}
int mid = (tree[p].ql + tree[p].qr) >> 1;
if (right <= mid) {
return getsum(p << 1, left, right);
}
if (left > mid) {
return getsum(p << 1 | 1, left, right);
}
return getsum(p << 1, left, mid) + getsum(p << 1 | 1, mid + 1, right);
}
int qmax(int u, int v) {
int rt = -2147483646;
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) {
std::swap(u, v);
}
rt = std::max(rt, getmax(1, id[top[u]], id[u]));
u = fa[top[u]];
}
if (dep[u] < dep[v]) {
std::swap(u, v);
}
rt = std::max(rt, getmax(1, id[v], id[u]));
return rt;
}
int qsum(int u, int v) {
int rt = 0;
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) {
std::swap(u, v);
}
rt += getsum(1, id[top[u]], id[u]);
u = fa[top[u]];
}
if (dep[u] < dep[v]) {
std::swap(u, v);
}
rt += getsum(1, id[v], id[u]);
return rt;
} int main(void) {
//freopen("in.txt", "r", stdin);
unsigned seed;
memset(head, -1, sizeof head);
memset(next, -1, sizeof next);
scanf("%d", &n);
seed += n;
for (int i = 1; i < n; ++i) {
scanf("%d%d", &t1, &t2);
ist(t1, t2);
ist(t2, t1);
seed += t1;
}
for (int i = 1; i <= n; ++i) {
scanf("%d", v + i);
} srand(seed);
root = rand() % n + 1;
dfs1(root);
dfs2(root, root);
make_tree(1, 1, n); scanf("%d", &q);
while (q--) {
scanf("%s%d%d", opr, &t1, &t2);
if (opr[1] == 'M') {
printf("%d\n", qmax(t1, t2));
}
else if (opr[1] == 'S') {
printf("%d\n", qsum(t1, t2));
}
else {
upd(1, id[t1], t2);
}
}
return 0;
}
_bzoj1036 [ZJOI2008]树的统计Count【树链剖分】的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
- Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 11102 Solved: 4490[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...
- bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题
[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...
- bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 16294 Solved: 6645[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14982 Solved: 6081[Submit ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)(线段树单点修改)
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14968 Solved: 6079[Submit][Stat ...
- Cogs 1688. [ZJOI2008]树的统计Count(树链剖分+线段树||LCT)
[ZJOI2008]树的统计Count ★★★ 输入文件:bzoj_1036.in 输出文件:bzoj_1036.out 简单对比 时间限制:5 s 内存限制:162 MB [题目描述] 一棵树上有n ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
随机推荐
- 使用python分析解压zip、jar包等
python内置zipfile import zipfile, os zipFile = zipfile.ZipFile(os.path.join(os.getcwd(), 'txt.zip')) f ...
- Android切图注意事项
1.App Logo大小共五种: 48*48 72*72 96*96 144*144 192*192 2. App启动页所需尺寸: 320×480 480×800 720*1280 1080*1920 ...
- JAVA_the user operation is waiting怎么办
彻底解决 MyEclipse出现the user operation is waiting的问题 2011-05-31 10:32:30| 分类: 软件编程 | 标签:java myecli ...
- 在Oracle数据库中使用NFS,怎样调优?
MOS上有好多文章,基本上都跑不了以下三点: Setup can make a big difference 1. Network topology and load 2. NFS mount opt ...
- 各种“GND”
资料来自网上,把个人觉得靠谱的摘取下来 1.地分类: a)直流地:直流电路“地”,零电位参考点: b)交流地:交流电的零线.要与地线区别开,不过,有时候拉电入户之前会把地线和零线接在一起: c)功率地 ...
- HDU 1824 Let's go home (2-SAT判定)
Let's go home Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- Cocos2d-X-3.0 之后的版本的环境搭建
Cocos2d-X-3.0 之后的版本的环境搭建 由于cocos2d游戏开发引擎更新十分频繁,官方文档同步不够及时和完善.所以不要照着官方文档来照做生成工程. <点击图片就能进入网站> ...
- linux中用anaconda使用不同版本python
1.使用命令conda create --name python36 python=3.6 #你想使用哪个版本就下载哪个版本,--name后面跟的是该虚拟环境的名称 2.需要使用python3.6时 ...
- 【IOS】启动画面
总述: 两种方式,一种是使用系统自带的.按规则定义启动图片名称就可以,显示为1秒,要想延长时间,用[nsthread sleepForTimeInterval:5.0] ,还有一种就是自己定义ui ...
- 包管理 import debug 模块管理 module
import sys, os this_file_abspath = os.path.dirname(os.path.abspath(__file__)) ProjectUtil_path = '{} ...