题解 [ZJOI2008]树的统计Count
[ZJOI2008]树的统计Count
Description
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
Input
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
Output
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input
4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
Sample Output
4
1
2
2
10
6
5
6
5
16
Hint
Source
耒阳大世界(衡阳八中) OJ 1036
树链剖分, 动态树
解析
就是一道模板题!!
直接树链剖分再线段树维护就行了啊!
当然,我们都知道这个东西主要是难调。
所以总结一下本蒟蒻经常犯的错误吧!
- dfs时要记得记录节点的在线段树上的编号。
- 节点号和它在线段树上的编号一定要分清楚。
- 在修改和查询的时候一定要记得pushdown。
- pushdown时一定要用tag乘区间长度。
- pushdown后要记得清除tag。
- 还有什么问题欢迎补充。
上代码吧:
#include <bits/stdc++.h>
#define ls(a) (a<<1)
#define rs(a) (a<<1|1)
using namespace std; struct linetree{
int l,r;
int maxn/*最大权值*/,sum/*权值和*/;
};
struct node/*节点的编号*/{
int son/*重儿子*/,fa/*父亲*/,dep;
int top/*重链顶端的编号*/,id/*线段树中的编号*/;
int val,size/*儿子数目*/;
};
struct line{
int next,to;
};
line e[];
node a[];
linetree t[];
int pre[]/*线段树中为i的点的实际编号*/;
int head[],cnt=;
int n,q;
string s; void add(int x,int y){
e[++cnt].to=head[x];
e[cnt].next=y;
head[x]=cnt;
} void dfs1(int x){
a[x].dep=a[a[x].fa].dep+;
a[x].size=;
for(int i=head[x];i;i=e[i].to){
int k=e[i].next;
if(k==a[x].fa) continue;
a[k].fa=x;
dfs1(k);
a[x].size+=a[k].size;
if(!a[x].son||a[a[x].son].size<a[k].size) a[x].son=k;
}
} void dfs2(int x,int top){
a[x].top=top;
a[x].id=++cnt;
pre[cnt]=x;
if(a[x].son) dfs2(a[x].son,top);
for(int i=head[x];i;i=e[i].to){
int k=e[i].next;
if(k==a[x].fa||k==a[x].son) continue;
dfs2(k,k);
}
} void pushup(int p){
t[p].maxn=max(t[ls(p)].maxn,t[rs(p)].maxn);
t[p].sum=t[ls(p)].sum+t[rs(p)].sum;
} void build(int p,int l,int r){
t[p].l=l;t[p].r=r;
if(l==r){
t[p].sum=t[p].maxn=a[pre[l]].val;
return ;
}
int mid=(l+r)/;
build(ls(p),l,mid);
build(rs(p),mid+,r);
pushup(p);
} void change(int p,int x/*x为线段树中的编号(不是原来的)*/,int k){
if(t[p].l==t[p].r){
a[pre[x]].val=k;
t[p].maxn=t[p].sum=k;
return ;
}
int mid=(t[p].l+t[p].r)/;
if(x<=mid) change(ls(p),x,k);
else if(x>mid) change(rs(p),x,k);
pushup(p);
} int ask(int p,int l,int r,int opt){
if(l>r) swap(l,r);
if(t[p].l>=l&&t[p].r<=r){
if(opt==) return t[p].sum;
else if(opt==) return t[p].maxn;
}
int ret=,res=-0x3f3f3f3f;
int mid=(t[p].l+t[p].r)/;
if(l<=mid){
if(opt==) ret+=ask(ls(p),l,r,opt);
else if(opt==) res=max(res,ask(ls(p),l,r,opt));
}
if(r>mid){
if(opt==) ret+=ask(rs(p),l,r,opt);
else if(opt==) res=max(res,ask(rs(p),l,r,opt));
}
if(opt==) return ret;
return res;
} int askmax(int x,int y){
int ans=-0x3f3f3f3f;
while(a[x].top!=a[y].top){
if(a[a[x].top].dep<a[a[y].top].dep) swap(x,y);
ans=max(ans,ask(,a[a[x].top].id,a[x].id,));
x=a[a[x].top].fa;
}
if(a[x].dep>a[y].dep) swap(x,y);
ans=max(ans,ask(,a[x].id,a[y].id,));
return ans;
} int asksum(int x,int y){
int ans=;
while(a[x].top!=a[y].top){
if(a[a[x].top].dep<a[a[y].top].dep) swap(x,y);
ans+=ask(,a[a[x].top].id,a[x].id,);
x=a[a[x].top].fa;
}
if(a[x].dep>a[y].dep) swap(x,y);
ans+=ask(,a[x].id,a[y].id,);
return ans;
} int main(){
scanf("%d",&n);
for(int i=;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
for(int i=;i<=n*;i++){
t[i].maxn=-0x3f3f3f3f;
}
for(int i=;i<=n;i++){
scanf("%d",&a[i].val);
}
dfs1();
cnt=;
dfs2(,);
build(,,n);
scanf("%d",&q);
for(int i=;i<=q;i++){
int x,y;
cin>>s;
scanf("%d%d",&x,&y);
if(s[]=='H'){
change(,a[x].id,y);
}
else if(s[]=='M'){
printf("%d\n",askmax(x,y));
}
else if(s[]=='S'){
printf("%d\n",asksum(x,y));
}
}
return ;
}
题解 [ZJOI2008]树的统计Count的更多相关文章
- 【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 ...
- 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 7496 Solved: 3078[Submit] ...
- BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14982 Solved: 6081[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- bzoj1036 [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 12646 Solved: 5085 [Subm ...
- 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 ...
- 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12266 Solved: 4945[Submit ...
随机推荐
- kettle转换设置变量,校验输出新变量
背景:有很多小的转换需要串联起来,如果前一个执行成功,后面继续接着执行,如果执行等待中,就让程序等一会再次获取数据分析,如果失败就中止,成功就进行下一个转换,以此类推.... 需求:通过job把参数传 ...
- HTML+CSS常用代码(笔记)
注释标签:对代码进行说明 <!-- 单行注释,也可以对多行文字进行注释 --> 常用格式标签 <b>加粗</b> <i>斜体</i> < ...
- 黑科技——树剖两次dfs转一次dfs!
黑科技--树剖两次\(dfs\)转一次\(dfs\)! 重所周知,树链剖分通常是要\(dfs\)两次的,就像这样: int Fa[N],dep[N],Sz[N],son[N]; void dfs1( ...
- fio安装使用
# wget http://brick.kernel.dk/snaps/fio-2.2.5.tar.gz # tar xvf fio-2.2.5.tar.gz# cd fio-2.2.5# ./con ...
- Separate String
Separate String 时间限制: 1 Sec 内存限制: 128 MB提交: 50 解决: 16 题目描述 You are given a string t and a set S of ...
- Django入门:操作数据库(Model)
Django-Model操作数据库(增删改查.连表结构) 一.数据库操作 1.创建model表 基本结构 1 2 3 4 5 6 from django.db import model ...
- 移动站Web开发图片自适应两种常见情况解决方案
本文主要说的是Web中图片根据手机屏幕大小自适应居中显示,图片自适应两种常见情况解决方案.开始吧 在做配合手机客户端的Web wap页面时,发现文章对图片显示的需求有两种特别重要的情况,一是对于图集, ...
- Windows+Nginx+Tomcat整合的安装与配置学习笔记
以下全部是nginx在window7下运行的: nginx学习总结: 我的是放在F盘 1.启动:F:\nginx-1.10.2\nginx-1.10.2>start nginx.exe(找到相应 ...
- vue 日常开发小细节
1. element-ui 日期选区禁用,设置属性 disabledDate: (time) => { const curDate = (new Date()).getTime() const ...
- Delphi 使用Tabel组件的记录查找
樊伟胜