传送门

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】树的统计(树链剖分)相关推荐

  1. [luogu P2590 ZJOI2008] 树的统计 (树链剖分)

    题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...

  2. BZOJ1036[ZJOI2008]树的统计——树链剖分+线段树

    题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...

  3. zjoi 2008 树的统计——树链剖分

    比较基础的一道树链剖分的题 大概还是得说说思路 树链剖分是将树剖成很多条链,比较常见的剖法是按儿子的size来剖分,剖分完后对于这课树的询问用线段树维护--比如求路径和的话--随着他们各自的链向上走, ...

  4. P3899 [湖南集训]更为厉害(线段树合并、长链剖分、二维数点)

    P3899 [湖南集训]更为厉害 若 deepb<deepa\text{deep}_b<\text{deep}_adeepb​<deepa​:c 在点 a 的子树中,根据乘法原理计算 ...

  5. [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分

    题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...

  6. [ZJOI2008] 树的统计(树链剖分)

    题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...

  7. ZJOI2008 树的统计 树链剖分学习

    水题,这次都没有给我傻逼的机会了,1A过了.直接上代码了 #include <iostream> #include <cstdio> #include <cstring& ...

  8. 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)

    P2590 [ZJOI2008]树的统计 I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问 ...

  9. 树链剖分(bzoj 1036: [ZJOI2008]树的统计Count)

    树链剖分: 把一棵树剖分为若干条链,然后利用数据结构(树状数组,SBT,Splay,线段树等等)去维护每一条链,复杂度 为O(logn),总体复杂度O(nlog²n) 步骤: ①将树的边分成重边和轻边 ...

  10. 【树链剖分】「ZJOI2008」树的统计

    前置知识 树链剖分的思想及能解决的问题 树链剖分用于将树分割成若干条链的形式,以维护树上路径的信息. 具体来说,将整棵树剖分为若干条链,使它组合成线性结构,然后用其他的数据结构维护信息. 树链剖分(树 ...

最新文章

  1. Linux之Nginx
  2. 面向对象是软件开发范式的根本性颠覆: 主体建模, 非目标导向, 松耦合, 非逻辑分解, 软件进化...
  3. sql server与java实例_Origin数据处理实例教程50节02040101
  4. 自建Git服务器系列——Gitea(Gogs的孪生兄弟)
  5. C#程序将DLL包进EXE方法
  6. mfc连接mysql增删改查_java实现mysql数据库增删改查
  7. FPGA SPI总线协议简介
  8. 继淘宝特价版之后 闲鱼已向微信提交小程序申请
  9. question1 赋值运算操作符
  10. python数值运算代码_Python数值
  11. Python 2.6 升级到 2.7
  12. 壁面函数matlab,Y+的查看及FLUENT壁面函数的选择
  13. 通过ip查看主机名和端口占用情况
  14. 在Visual Studio中对Epicor10进行二次开发
  15. 如何复制Google云端硬盘文件夹
  16. Java集成融云服务端
  17. html布局属性,hTML之FLEX布局属性
  18. Pandas+Pyecharts | 招聘信息数据可视化
  19. R语言 第三方软件包的下载及安装
  20. java书籍 李清华_201772020113 李清華《面向對象程序設計(java)》第18周學習總結...

热门文章

  1. mysql并发更新数据,多用户并发修改数据解决方案。
  2. 2021-2027年中国网络安全内容审查行业市场研究及前瞻分析报告
  3. 2022-2028年中国在线旅行预订市场投资分析及前景预测报告
  4. 【机器学习】RNN循环神经网络
  5. sqlplus连接时出现错误:shared memory realm does not exist 解决
  6. LeetCode简单题之数组的相对排序
  7. 现代传感器的接口:中断驱动的ADC驱动程序
  8. 【CV】Pytorch一小时入门教程-代码详解
  9. [JAVAEE] 使用Postman测试接口
  10. 常用MySQL函数存储过程_解析MySQL存储过程、常用函数代码