【ZJOI2008】树的统计(树链剖分)
传送门
Solution:
就是树链剖分入门题啦~
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define N 30005
#define M 200005
#define lson now<<1
#define rson now<<1|1
#define INF 0x7fffffff
using namespace std;
int n,tot,first[N],val[N];
int father[N],size[N],maxson[N],depth[N],top[N],id[N],sign,wnew[N];
int ans=0;
struct Edge
{int to,next;
}edge[2*N];
inline void addedge(int x,int y)
{tot++;edge[tot].to=y;edge[tot].next=first[x];first[x]=tot;
}
struct node
{int l,r,sum,maxv;
}tree[4*N];
inline void build(int l,int r,int now)
{tree[now].l=l,tree[now].r=r,tree[now].sum=0,tree[now].maxv=0;if(l==r){tree[now].sum=wnew[l];tree[now].maxv=wnew[l];return;}int m=(l+r)>>1;build(l,m,lson);build(m+1,r,rson);tree[now].sum=tree[lson].sum+tree[rson].sum;tree[now].maxv=max(tree[lson].maxv,tree[rson].maxv);
}
inline void update(int now,int x,int k)
{if(tree[now].l==x&&tree[now].r==x){tree[now].sum=k;tree[now].maxv=k;return;}int m=(tree[now].l+tree[now].r)>>1;if(x<=m) update(lson,x,k);else update(rson,x,k);tree[now].sum=tree[lson].sum+tree[rson].sum;tree[now].maxv=max(tree[lson].maxv,tree[rson].maxv);
}
inline void query_sum(int l,int r,int now)
{if(l<=tree[now].l&&tree[now].r<=r) {ans+=tree[now].sum;return;}int m=(tree[now].l+tree[now].r)>>1;if(l<=m) query_sum(l,r,lson);if(r>m) query_sum(l,r,rson);
}
inline void query_max(int l,int r,int now)
{if(l<=tree[now].l&&tree[now].r<=r) {ans=max(ans,tree[now].maxv);return;}int m=(tree[now].l+tree[now].r)>>1;if(l<=m) query_max(l,r,lson);if(r>m) query_max(l,r,rson);
}
inline void dfs1(int now,int fa)
{father[now]=fa;size[now]=1;depth[now]=depth[fa]+1;for(int u=first[now];u;u=edge[u].next){int vis=edge[u].to;if(vis==fa) continue;dfs1(vis,now);size[now]+=size[vis];if(size[vis]>size[maxson[now]]) maxson[now]=vis;}
}
inline void dfs2(int now,int topf)
{id[now]=++sign;top[now]=topf;wnew[sign]=val[now];if(maxson[now]) dfs2(maxson[now],topf);for(int u=first[now];u;u=edge[u].next){int vis=edge[u].to;if(vis==father[now]||vis==maxson[now]) continue;dfs2(vis,vis);}
}
inline int qmax(int x,int y)
{int ret=-INF;while(top[x]!=top[y]){if(depth[top[x]]<depth[top[y]]) swap(x,y);//默认x比y深 ans=-INF;query_max(id[top[x]],id[x],1);ret=max(ret,ans);x=father[top[x]];}if(depth[x]<depth[y]) swap(x,y);ans=-INF;query_max(id[y],id[x],1);return max(ret,ans);
}
inline int qsum(int x,int y)
{int ret=0;while(top[x]!=top[y]){if(depth[top[x]]<depth[top[y]]) swap(x,y);//默认x比y浅ans=0;query_sum(id[top[x]],id[x],1);ret+=ans;x=father[top[x]];}if(depth[x]<depth[y]) swap(x,y);ans=0;query_sum(id[y],id[x],1);ret+=ans;return ret;
}
int main()
{cin>>n;for(int i=1;i<=n-1;i++){int x,y;cin>>x>>y;addedge(x,y);addedge(y,x);}for(int i=1;i<=n;i++) cin>>val[i];dfs1(1,0);dfs2(1,1);build(1,n,1);int Q;cin>>Q;while(Q--){string s;int x,y;cin>>s>>x>>y;if(s=="CHANGE") update(1,id[x],y);if(s=="QMAX") cout<<qmax(x,y)<<'\n';if(s=="QSUM") cout<<qsum(x,y)<<'\n';}return 0;
}
转载于:https://www.cnblogs.com/Patrickpwq/articles/9467483.html
【ZJOI2008】树的统计(树链剖分)相关推荐
- [luogu P2590 ZJOI2008] 树的统计 (树链剖分)
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- BZOJ1036[ZJOI2008]树的统计——树链剖分+线段树
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- zjoi 2008 树的统计——树链剖分
比较基础的一道树链剖分的题 大概还是得说说思路 树链剖分是将树剖成很多条链,比较常见的剖法是按儿子的size来剖分,剖分完后对于这课树的询问用线段树维护--比如求路径和的话--随着他们各自的链向上走, ...
- P3899 [湖南集训]更为厉害(线段树合并、长链剖分、二维数点)
P3899 [湖南集训]更为厉害 若 deepb<deepa\text{deep}_b<\text{deep}_adeepb<deepa:c 在点 a 的子树中,根据乘法原理计算 ...
- [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分
题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...
- [ZJOI2008] 树的统计(树链剖分)
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- ZJOI2008 树的统计 树链剖分学习
水题,这次都没有给我傻逼的机会了,1A过了.直接上代码了 #include <iostream> #include <cstdio> #include <cstring& ...
- 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)
P2590 [ZJOI2008]树的统计 I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问 ...
- 树链剖分(bzoj 1036: [ZJOI2008]树的统计Count)
树链剖分: 把一棵树剖分为若干条链,然后利用数据结构(树状数组,SBT,Splay,线段树等等)去维护每一条链,复杂度 为O(logn),总体复杂度O(nlog²n) 步骤: ①将树的边分成重边和轻边 ...
- 【树链剖分】「ZJOI2008」树的统计
前置知识 树链剖分的思想及能解决的问题 树链剖分用于将树分割成若干条链的形式,以维护树上路径的信息. 具体来说,将整棵树剖分为若干条链,使它组合成线性结构,然后用其他的数据结构维护信息. 树链剖分(树 ...
最新文章
- Linux之Nginx
- 面向对象是软件开发范式的根本性颠覆: 主体建模, 非目标导向, 松耦合, 非逻辑分解, 软件进化...
- sql server与java实例_Origin数据处理实例教程50节02040101
- 自建Git服务器系列——Gitea(Gogs的孪生兄弟)
- C#程序将DLL包进EXE方法
- mfc连接mysql增删改查_java实现mysql数据库增删改查
- FPGA SPI总线协议简介
- 继淘宝特价版之后 闲鱼已向微信提交小程序申请
- question1 赋值运算操作符
- python数值运算代码_Python数值
- Python 2.6 升级到 2.7
- 壁面函数matlab,Y+的查看及FLUENT壁面函数的选择
- 通过ip查看主机名和端口占用情况
- 在Visual Studio中对Epicor10进行二次开发
- 如何复制Google云端硬盘文件夹
- Java集成融云服务端
- html布局属性,hTML之FLEX布局属性
- Pandas+Pyecharts | 招聘信息数据可视化
- R语言 第三方软件包的下载及安装
- java书籍 李清华_201772020113 李清華《面向對象程序設計(java)》第18周學習總結...
热门文章
- mysql并发更新数据,多用户并发修改数据解决方案。
- 2021-2027年中国网络安全内容审查行业市场研究及前瞻分析报告
- 2022-2028年中国在线旅行预订市场投资分析及前景预测报告
- 【机器学习】RNN循环神经网络
- sqlplus连接时出现错误:shared memory realm does not exist 解决
- LeetCode简单题之数组的相对排序
- 现代传感器的接口:中断驱动的ADC驱动程序
- 【CV】Pytorch一小时入门教程-代码详解
- [JAVAEE] 使用Postman测试接口
- 常用MySQL函数存储过程_解析MySQL存储过程、常用函数代码