BZOJ 1036 [ZJOI2008]树的统计Count 动态维护树上求和与求最大值 LCT板题
模板,也可以用树链剖分+线段树做O(nlog2)O(nlog^2)O(nlog2)
用LCT做O(nlog)O(nlog)O(nlog)在乘上一个大于30的常数…然后LCT比树剖慢一倍…
CODE
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
template<typename T>inline void read(T &num) {
char ch; int flg = 1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flg=-flg;
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
num*=flg;
}
const int MAXN = 30005;
int n, q, u[MAXN], v[MAXN];
namespace LCT {
#define ls ch[x][0]
#define rs ch[x][1]
int ch[MAXN][2], fa[MAXN];
LL w[MAXN], sum[MAXN], mx[MAXN];
bool rev[MAXN];
inline bool isr(int x) { return ch[fa[x]][0] != x && ch[fa[x]][1] != x; } //判断是否为根
inline bool get(int x) { return x == ch[fa[x]][1]; }
inline void upd(int x) { //上传
sum[x] = sum[ls] + sum[rs] + w[x];
mx[x] = max(w[x], max(mx[ls], mx[rs]));
}
inline void rot(int x) {
int y = fa[x], z = fa[y], l = get(x), r = l^1;
if(!isr(y)) ch[z][get(y)] = x;
fa[ch[x][r]] = y; fa[y] = x; fa[x] = z;
ch[y][l] = ch[x][r]; ch[x][r] = y;
upd(y), upd(x);
}
inline void mt(int x) { if(rev[x]) rev[x] ^= 1, rev[ls] ^= 1, rev[rs] ^= 1, swap(ls, rs); } //下传
void mtpath(int x) { if(!isr(x)) mtpath(fa[x]); mt(x); }
inline void splay(int x) {
mtpath(x);
for(; !isr(x); rot(x))
if(!isr(fa[x])) rot(get(x)==get(fa[x])?fa[x]:x);
}
inline int access(int x) { int y=0;
for(; x; x=fa[y=x]) splay(x), ch[x][1]=y, upd(x);
return y;
}
inline void bert(int x) { access(x), splay(x), rev[x] ^= 1; } //换根
inline int sert(int x) { //找根
access(x), splay(x);
for(; ch[x][0]; x=ch[x][0]);
return x;
}
inline void link(int x, int y) {
bert(x);
if(sert(y) == x) return;
fa[x] = y;
}
inline void cut(int x, int y) {
bert(x), access(y), splay(y);
if(sert(y) != x || fa[x] != y || ch[x][1] != 0) return;
fa[x] = ch[y][0] = 0; upd(y);
}
inline void modify(int x, int val) {
splay(x), w[x] = val, upd(x);
}
inline int split(int x, int y) {
bert(x), access(y), splay(y);
return y;
}
inline int querymax(int x, int y) {
split(x, y); return mx[y];
}
inline int querysum(int x, int y) {
split(x, y); return sum[y];
}
}
using namespace LCT;
int main () {
read(n); mx[0] = -0x7f7f7f7f; //把0设成-无穷,因为upd的时候会访问到
for(int i = 1; i < n; ++i) read(u[i]), read(v[i]);
for(int i = 1; i <= n; ++i) read(w[i]);
for(int i = 1; i < n; ++i) link(u[i], v[i]);
read(q);
char s[10]; int x, y;
while(q--) {
scanf("%s", s); read(x), read(y);
if(s[1] == 'M') printf("%d\n", querymax(x, y));
else if(s[1] == 'S') printf("%d\n", querysum(x, y));
else modify(x, y);
}
}
BZOJ 1036 [ZJOI2008]树的统计Count 动态维护树上求和与求最大值 LCT板题的更多相关文章
- BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)
BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...
- 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12266 Solved: 4945[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 14354 Solved: 5802 [Subm ...
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10677 Solved: 4313[Submit ...
- Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 11102 Solved: 4490[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...
- 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: 21194 Solved: 8589[Submit ...
随机推荐
- kafka producer consumer demo(三)
我们在前面把集群搭建起来了,也设置了kafka broker的配置,下面我们用代码来实现一下客户端向kafka发送消息,consumer端从kafka消费数据.大家先不要着急着了解 各种参数的配置,先 ...
- redis通用命令
1.keys pattern 含义:查找所有符合给定模式(pattern)的key keys * 遍历所有key keys he[h-l]* 遍历以he开头,第三个字符为h-l之间的所有key key ...
- POJ1631_高深DP
按照那个图形研究比较了一会, 居然发现是最长上升子序列问题, 这个是真的牛逼!! 只不过是题目没有说的那么直白!
- Centos7下,宿主机nginx配合docker环境的php-fpm
一.安装docker并启动 yum install docker systemctl start docker 二.安装nginxCentOS 7默认不能从yum中安装nginx,原因可以自己搜索一下 ...
- mysql innodb数据库损坏导致无法启动
生产环境中的mysql突然启动不了,查了原因是innodb库错误,以前就遇到过这个问题,稀里糊涂的没解决,结果导致大量数据丢失.这些又遇到这个问题,果断把那个有问题的数据库移动了别的地方,启动了mys ...
- 利用Python进行数据分析_Numpy_基础_1
ndarray:多维数组 ndarray 每个数组元素必须是相同类型,每个数组都有shape和dtype对象. shape 表示数组大小 dtype 表示数组数据类型 array 如何创建一个数组? ...
- java包装类的缓存机制(转)
出处: java包装类的缓存机制 java 包装类的缓存机制,是在Java 5中引入的一个有助于节省内存.提高性能的功能,只有在自动装箱时有效 Integer包装类 举个栗子: Integer a = ...
- 【Trie】L 语言
[题目链接]: https://loj.ac/problem/10053 [题意]: 给出n个模式串.请问文本串是由多少个模式串组成的. [题解]: 当我学完AC自动机后,发现这个题目也太简单了吧. ...
- 简单分析BeanPostProcessor
1. 什么是BeanPostProcessorBeanPostProcessor是一个接口,有两个方法,分别是:Object postProcessBeforeInitialization(Objec ...
- Java面试题之Java虚拟机垃圾回收
JVM的垃圾回收机制,在内存充足的情况下,除非你显式的调用System.gc(),否则不会进行垃圾回收:在内存充足的情况下垃圾回收会自动运行. 一.引用计数算法 1.定义:引用计数算法会给对象添加一个 ...