【lct】bzoj1036 [ZJOI2008]树的统计Count
题意:给你一棵树,点带权,支持三种操作:单点修改;询问链上和;询问链上max。
这里的Query操作用了与上一题不太一样的做法(上一题用那种做法,因为在边带权的情况下换根太困难啦):
先ChangeRoot(U),然后Access(V),再Splay(V),询问V在辅助树中的左子树。
因为Splay的pushdown用了极为暴力的做法……故而跑得比原来写的链剖线段树慢一倍。不过常数不在意了。
#include<cstdio>
#include<iostream>
#include<stack>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 30005
int fa[maxn],c[maxn][2],siz[maxn];
bool is_root[maxn],delta[maxn];
int val[maxn],totalval[maxn],maxv[maxn];
void Mark(int x){
if(x){
delta[x]^=1;
}
}
void Maintain(int x)
{
siz[x]=siz[c[x][0]]+siz[c[x][1]]+1;
totalval[x]=totalval[c[x][0]]+totalval[c[x][1]]+val[x];
maxv[x]=val[x];
if(c[x][0]){
maxv[x]=max(maxv[x],maxv[c[x][0]]);
}
if(c[x][1]){
maxv[x]=max(maxv[x],maxv[c[x][1]]);
}
}
void pushdown(int x){
if(delta[x]){
Mark(c[x][0]);
Mark(c[x][1]);
swap(c[x][0],c[x][1]);
delta[x]=0;
}
}
void Rotate(int x,bool flag)
{
int y=fa[x];
c[y][!flag]=c[x][flag];
if(c[x][flag]){
fa[c[x][flag]]=y;
}
if(fa[y] && c[fa[y]][c[fa[y]][1]==y]==y){
c[fa[y]][c[fa[y]][1]==y]=x;
}
fa[x]=fa[y];
c[x][flag]=y;
fa[y]=x;
if(is_root[y]){
is_root[y]=0;
is_root[x]=1;
}
Maintain(y);
Maintain(x);
}
stack<int>st;
void Splay(int x)
{
pushdown(x);
if(!x || is_root[x]){
return;
}
int U=x;
while(!is_root[U]){
st.push(U);
U=fa[U];
}
st.push(U);
while(!st.empty()){
pushdown(st.top());
st.pop();
}
int y;
while(y=fa[x],(!is_root[x])){
if(is_root[y]){
Rotate(x,c[y][0]==x);
}
else{
if((c[y][0]==x)==(c[fa[y]][0]==y)){
Rotate(y,c[fa[y]][0]==y);
}
else{
Rotate(x,c[y][0]==x);
y=fa[x];
}
Rotate(x,c[y][0]==x);
}
}
Maintain(x);
}
void Access(int x){
int y;
Splay(x);
while(fa[x]){
y=fa[x];
Splay(y);
Splay(x);
if(c[y][1]){
is_root[c[y][1]]=1;
}
is_root[x]=0;
c[y][1]=x;
Splay(x);
}
if(c[x][1]){
is_root[c[x][1]]=1;
c[x][1]=0;
}
}
void ChangeRoot(int x){
Access(x);
Splay(x);
Mark(x);
}
int QSum(int U,int V){
ChangeRoot(U);
Access(V);
Splay(V);
return val[V]+totalval[c[V][0]];
}
int QMax(int U,int V){
ChangeRoot(U);
Access(V);
Splay(V);
if(!c[V][0]){
return val[V];
}
else{
return max(val[V],maxv[c[V][0]]);
}
}
int n,m;
int v[maxn<<1],nex[maxn<<1],first[maxn],e;
void AddEdge(int U,int V){
v[++e]=V;
nex[e]=first[U];
first[U]=e;
}
int a[maxn];
void dfs(int U){
siz[U]=1;
is_root[U]=1;
val[U]=totalval[U]=maxv[U]=a[U];
for(int i=first[U];i;i=nex[i]){
if(!siz[v[i]]){
fa[v[i]]=U;
dfs(v[i]);
}
}
}
int main(){
// freopen("bzoj1036.in","r",stdin);
char op[10];
int x,y;
scanf("%d",&n);
for(int i=1;i<n;++i){
scanf("%d%d",&x,&y);
AddEdge(x,y);
AddEdge(y,x);
}
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}
dfs(1);
scanf("%d",&m);
for(int i=1;i<=m;++i){
scanf("%s%d%d",op,&x,&y);
if(op[3]=='N'){
Splay(x);
val[x]=y;
Maintain(x);
}
else if(op[3]=='M'){
printf("%d\n",QSum(x,y));
}
else{
printf("%d\n",QMax(x,y));
}
}
return 0;
}
【lct】bzoj1036 [ZJOI2008]树的统计Count的更多相关文章
- [BZOJ1036][ZJOI2008]树的统计Count 解题报告|树链剖分
树链剖分 简单来说就是数据结构在树上的应用.常用的为线段树splay等.(可现在splay还不会敲囧) 重链剖分: 将树上的边分成轻链和重链. 重边为每个节点到它子树最大的儿子的边,其余为轻边. 设( ...
- bzoj1036 [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 12646 Solved: 5085 [Subm ...
- bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题
[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...
- bzoj千题计划124:bzoj1036: [ZJOI2008]树的统计Count
http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分板子题 #include<cstdio> #include<iost ...
- [BZOJ1036] [ZJOI2008] 树的统计Count (LCT)
Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...
- bzoj1036 [ZJOI2008]树的统计Count——LCT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1036 LCT水题! 然而没有1A(咬牙)! 注意值有负数,所以取 max 的话要把作为“哨兵 ...
- BZOJ1036 [ZJOI2008]树的统计Count 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1036 题意概括 一个树,每个节点有一个权值.3种操作. 1:修改某一个节点的权值. 2:询问某两个 ...
- BZOJ1036[ZJOI2008]树的统计Count 题解
题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.有一些操作:1.把结点u的权值改为t:2.询问从点u到点v的路径上的节点的最大权值 3.询问从点u到点v的路径上的节点的权值和 ...
- bzoj1036 zjoi2008 树的统计 count
填坑= =第一道裸树剖 #include<cstdio> #include<algorithm> #include<cstring> #include<cst ...
随机推荐
- 24、简述Python的深浅拷贝以及应用场景
深浅拷贝的原理 深浅拷贝用法来自copy模块. 导入模块:import copy 浅拷贝:copy.copy 深拷贝:copy.deepcopy 字面理解:浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝 ...
- docker ubuntu容器更换阿里源(转)
问题:使用docker 利用下载的ubuntu镜像启动容器时,使用的源下载更新软件的速度较慢. 解决这个问题的方法是跟新ubuntu容器的源 示例:以ubuntu为基础镜像 启动一个名称为 test0 ...
- 高性能优秀的服务框架-dubbo介绍
先来了解一下这些年架构的变化,下面的故事是我编的.... "传统架构":很多年前,刚学完JavaWeb开发的我凭借一人之力就开发了一个网站,网站 所有的功能和应用都集中在一起,方便 ...
- Linux Kernel代码艺术——数组初始化【转】
转自:http://www.cnblogs.com/hazir/p/array_initialization.html 前几天看内核中系统调用代码,在系统调用向量表初始化中,有下面这段代码写的让我有点 ...
- 细说show slave status参数详解(最全)【转】
在搭建好mysql主从之后,我们一般在从库上通过命令 show slave status\G 来查看主从的状态,会有很多的参数,接下来笔者就带大家好好的了解这些参数 root@localhost (n ...
- 013 GC机制
本文转自:https://www.cnblogs.com/shudonghe/p/3457990.html 最近还是在找工作,在面试某移动互联网公司之前认为自己对Java的GC机制已经相当了解,其他面 ...
- Linux 不常用命令总结
1. vim编辑模式下,搜索,/user,跳转下一个,小写的n 2.
- awk中NF,NR的含义
awk中NF和NR的意义,其实你已经知道NF和NR的意义了,NF代表的是一个文本文件中一行(一条记录)中的字段个数,NR代表的是这个文本文件的行数(记录数).在编程时特别是在数据处理时经常用到.建议你 ...
- ~Delphi const 杂谈~
来自:http://www.cnblogs.com/tibetwolf/articles/1785744.html ------------------------------------------ ...
- Spring学习-理解IOC和依赖注入
最近刚买了一本介绍ssm框架的书,里面主要对Mybatis.spring.springmvc和redis做了很多的讲解,个人觉得虽然有的内容我看不懂,但是整体上还是不错的.最近正在学习中,一边学习一边 ...