[luogu2590][bzoj1036][ZJOI2008]树的统计
题目描述
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身。
感想
感觉省选中的树剖题目还是有点多的呀,而且全都是模板题,巨简单~~,QAQ。
题解
今天看到了LCT的做法,感觉不会。写一篇树链剖分的题解。
既然知道是树剖,那么就只要套模板。
第一个操作:实际操作就是单点修改\(idx[u]\)
第二个操作,和第三个操作:都是树上的路径查询,还是模板。
\(ps.\)要注意,这个数存在负数,虽然对求和没有影响,但是在求最大值的时候需要从\(-inf\)开始。
ac代码
#include<bits/stdc++.h>
#define N 30005
#define LL long long
#define inf 0x3f3f3f3f
using namespace std;
int read(){
int w=0,x=0;char ch=0;
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return w?-x:x;
}
int H[N],son[N],dep[N],top[N],sz[N],fa[N],idx[N],a[N],w[N];
int cnt,tot,n;
struct edge{
int to,nt;
}E[N<<1];
void addedge(int u,int v){
E[++cnt]=(edge){v,H[u]}; H[u]=cnt;
E[++cnt]=(edge){u,H[v]}; H[v]=cnt;
}
struct Segment_tree{
#define ls (nod<<1)
#define rs (nod<<1|1)
#define mid ((l+r)>>1)
struct node{
int l,r;
LL mx,s;
}tr[N<<2];
void pushup(int nod){tr[nod].s=tr[ls].s+tr[rs].s; tr[nod].mx=max(tr[ls].mx,tr[rs].mx);}
void build(int l,int r,int nod,int *a){
tr[nod].l=l; tr[nod].r=r;
if(l==r){tr[nod].mx=tr[nod].s=a[l]; return;}
build(l,mid,ls,a); build(mid+1,r,rs,a);
pushup(nod);
}
void update_point(int nod,int k,int w){
int l=tr[nod].l,r=tr[nod].r;
if(l==r){tr[nod].mx=tr[nod].s=w;return;}
if(k<=mid) update_point(ls,k,w);
else update_point(rs,k,w);
pushup(nod);
}
LL query_sec_sum(int nod,int ql,int qr){
int l=tr[nod].l,r=tr[nod].r; LL res=0;
if(ql<=l&&r<=qr) return tr[nod].s;
if(ql<=mid) res+=query_sec_sum(ls,ql,qr);
if(qr>mid) res+=query_sec_sum(rs,ql,qr);
return res;
}
LL query_sec_max(int nod,int ql,int qr){
int l=tr[nod].l,r=tr[nod].r; LL res=-inf;
if(ql<=l&&r<=qr) return tr[nod].mx;
if(ql<=mid) res=max(res,query_sec_max(ls,ql,qr));
if(qr>mid) res=max(res,query_sec_max(rs,ql,qr));
return res;
}
}tr;
void dfs1(int u,int ft,int dp){
fa[u]=ft; dep[u]=dp; sz[u]=1;
int maxson=-1;
for(int e=H[u];e;e=E[e].nt){
int v=E[e].to; if(v==fa[u]) continue;
dfs1(v,u,dp+1); sz[u]+=sz[v];
if(sz[v]>maxson) maxson=sz[v],son[u]=v;
}
}
void dfs2(int u,int tp){
top[u]=tp; idx[u]=++tot; a[tot]=w[u];
if(!son[u]) return; dfs2(son[u],tp);
for(int e=H[u];e;e=E[e].nt){
int v=E[e].to; if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
LL query_sum(int u,int v){
LL res=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res+=tr.query_sec_sum(1,idx[top[u]],idx[u]);
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
res+=tr.query_sec_sum(1,idx[u],idx[v]);
return res;
}
LL query_max(int u,int v){
LL res=-inf;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res=max(res,tr.query_sec_max(1,idx[top[u]],idx[u]));
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
res=max(res,tr.query_sec_max(1,idx[u],idx[v]));
return res;
}
int main(){
cnt=tot=0;
n=read();
for(int i=1;i<n;i++) addedge(read(),read());
for(int i=1;i<=n;i++) w[i]=read();
dfs1(1,0,1); dfs2(1,1); tr.build(1,n,1,a);
int q=read();
while(q--){
char opt[10]; scanf("%s",opt); int u=read(),x=read();
if(opt[0]=='C') tr.update_point(1,idx[u],x);
else{
if(opt[1]=='M') printf("%lld\n",query_max(u,x));
else printf("%lld\n",query_sum(u,x));
}
}
return 0;
}
[luogu2590][bzoj1036][ZJOI2008]树的统计的更多相关文章
- [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 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1036 题意概括 一个树,每个节点有一个权值.3种操作. 1:修改某一个节点的权值. 2:询问某两个 ...
- 【lct】bzoj1036 [ZJOI2008]树的统计Count
题意:给你一棵树,点带权,支持三种操作:单点修改:询问链上和:询问链上max. 这里的Query操作用了与上一题不太一样的做法(上一题用那种做法,因为在边带权的情况下换根太困难啦): 先ChangeR ...
- 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 ...
- bzoj1036 [ZJOI2008]树的统计
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从 ...
随机推荐
- 【转】单KEY业务,数据库水平切分架构实践
本文将以“用户中心”为例,介绍“单KEY”类业务,随着数据量的逐步增大,数据库性能显著降低,数据库水平切分相关的架构实践: 如何来实施水平切分 水平切分后常见的问题 典型问题的优化思路及实践 一.用户 ...
- GitFlow原理浅析
一.Git优点 分布式存储 , 本地仓库包含了远程仓库的所有内容 . 安全性高 , 远程仓库文件丢失了也不怕 优秀的分支模型 , 创建/合并分支非常的方便 方便快速 , 由于代码本地都有存储 , 所以 ...
- myeclipse、maven、tomcat、jdk技巧和坑【待完善】
公司使用前后不分离或半分离的springmvc + maven ,自己不得不研究研究myeclipse.maven.tomcat等等 开发环境搭建:坑一: Unable to process Jar ...
- VS2010、VS2012、VS2013、VS2015、VS2017各版本产品激活秘钥
Visual Studio 2017(VS2017) 企业版 Enterprise 注册码:NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Visual Studio 2017(VS201 ...
- 2018年高教社杯全国大学生数学建模竞赛B题解题思路
题目 先贴下B题的题目吧 问题B 智能RGV的动态调度策略 图1是一个智能加工系统的示意图,由8台计算机数控机床(Computer Number Controller,CNC).1辆轨道式自动引 ...
- tomcat内存溢出问题记录
问题说明:公司内网环境中部署的jenkins代码发版平台突然不能访问了,查看tomcat的catalina.out日志发现报错如下: [root@redmine logs]# tail -f /srv ...
- this.$http.post ||this.$http.put||vue 获取url参
getClasslist() { this.$http.get('/xxxxx/childlist', { params: { ServiceUnitId: localStorage.getItem( ...
- Onezero团队第三次站立会议随感
>首先这是一个关于Android的小应用APP(记账本) >在Java基础薄弱的基础上尝试Android开发,让我感觉力不从心. >说实话本迭代周在程序设计,确实让我头疼,不知道怎么 ...
- 《移山之道》Reading Task
老师布置的阅读任务虽然是附加的作业,但是对我来说是个很好的学习机会.软件工程主要是对工程的开发进行学习,毕竟在学校老师教了那么多的知识,我们课下做了那么多的练习并没有提高我们做一个工程的能力.一个项目 ...
- 【Beta阶段】第十次Scrum Meeting!!!
每日任务内容: 本次会议为第十次Scrum Meeting会议~ 本次会议为团队Beta阶段的最后一次会议!! 队员 今日完成任务 刘乾 #136(完成一半,今晨发布) 团队博客撰写 https:// ...