_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 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
随机推荐
- how to read openstack code: service plugin
We have learned core plugin, service plugin and extension in last post. Now let`s review: Core Plugi ...
- Android自带的分享功能案例
MainActivity的代码 package com.hpsvse.weiboshare; import java.io.File; import android.net.Uri; import a ...
- graph driver-device mapper-03thin pool基本操作
// 在thin pool中创建一个新thin device // 调用路径:driver.Create() 1.1 func (devices *DeviceSet) AddDevice(hash, ...
- python 【第三篇】函数基础
深浅拷贝 set是一个无序且不重复的元素集合访问速度快天生解决重复问题 #!/usr/bin/env python3 # -*- coding:utf-8 -*- #深浅拷贝 import copy ...
- inter 也支持linux开发了
http://www.intel.cn/content/www/cn/zh/intelligent-systems/bay-trail/atom-processor-e3800-family-over ...
- Linq To Entities中的动态排序
换了工作有一个月了,一样的工作.一样的代码.一样的体力活仍就…… Linq To Entityes 也是不新玩意了,近半年来也一直与之打交道,但一直也没对其深究过.今天新加的功能要对所有列支持排序,这 ...
- rip是典型的距离矢量动态路由协议。Ospf是链路状态型的协议
网络工程师十个常见面试问题-看准网 https://m.kanzhun.com/k-mianshiwenti/1465113.html 两者都属于IGP协议,rip是典型的距离矢量动态路由协议.Osp ...
- HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...
- HDU - 1150 Machine Schedule(最小点覆盖数)
1.有两台机器A和B以及N个需要运行的任务.A机器有n种不同的模式,B机器有m种不同的模式,而每个任务都恰好在一台机器上运行.如果它在机器A上运行,则机器A需要设置为模式xi,如果它在机器B上运行,则 ...
- Eclipse 插件管理
查看已安装的插件: [help]⇒ [About Eclipse]⇒ [Installed Softwares] 1. 常用插件 maven:安装步骤如下: [help]⇒ [Install new ...