题意

一棵树上有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本身

对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

分析

树剖模板题。时间复杂度\(O(n + q\log n)\)

代码

BZOJ因为我那个major不让我过编译……只好在洛谷上交了。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;
rg char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') w=-1;
ch=getchar();
}
while(isdigit(ch))
data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x){
return x=read<T>();
}
typedef long long ll; co int N=3e4+1;
std::vector<int> g[N];
int n,w[N],fa[N],dep[N],siz[N],son[N],top[N],pos[N],dfn,ref[N];
namespace T{
int max[N*4],sum[N*4];
#define lson x<<1
#define rson x<<1|1
void pushup(int x){
max[x]=std::max(max[lson],max[rson]);
sum[x]=sum[lson]+sum[rson];
}
void build(int x,int l,int r){
if(l==r){
max[x]=sum[x]=w[ref[l]];
return;
}
int mid=(l+r)>>1;
build(lson,l,mid),build(rson,mid+1,r);
pushup(x);
}
void modify(int x,int l,int r,int p,int v){
if(l==r){
max[x]=sum[x]=v;
return;
}
int mid=(l+r)>>1;
if(p<=mid) modify(lson,l,mid,p,v);
else modify(rson,mid+1,r,p,v);
pushup(x);
}
int major(int x,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) return max[x];
int mid=(l+r)>>1;
if(qr<=mid) return major(lson,l,mid,ql,qr);
if(ql>mid) return major(rson,mid+1,r,ql,qr);
return std::max(major(lson,l,mid,ql,qr),major(rson,mid+1,r,ql,qr));
}
int summation(int x,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) return sum[x];
int mid=(l+r)>>1;
if(qr<=mid) return summation(lson,l,mid,ql,qr);
if(ql>mid) return summation(rson,mid+1,r,ql,qr);
return summation(lson,l,mid,ql,qr)+summation(rson,mid+1,r,ql,qr);
}
}
void dfs1(int x,int fa){
::fa[x]=fa,dep[x]=dep[fa]+1,siz[x]=1;
for(int i=0;i<g[x].size();++i){
int y=g[x][i];
if(y==fa) continue;
dfs1(y,x),siz[x]+=siz[y];
if(siz[y]>siz[son[x]]) son[x]=y;
}
}
void dfs2(int x,int top){
::top[x]=top,pos[x]=++dfn,ref[dfn]=x;
if(!son[x]) return;
dfs2(son[x],top);
for(int i=0;i<g[x].size();++i){
int y=g[x][i];
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
}
void modify(int x,int v){
T::modify(1,1,n,pos[x],v);
}
int major(int x,int y){
int ans=-30000;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
ans=std::max(ans,T::major(1,1,n,pos[top[x]],pos[x]));
x=fa[top[x]];
}
if(dep[x]<dep[y]) std::swap(x,y);
ans=std::max(ans,T::major(1,1,n,pos[y],pos[x]));
return ans;
}
int summation(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
ans+=T::summation(1,1,n,pos[top[x]],pos[x]);
x=fa[top[x]];
}
if(dep[x]<dep[y]) std::swap(x,y);
ans+=T::summation(1,1,n,pos[y],pos[x]);
return ans;
}
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(n);
for(int i=1;i<n;++i){
int x=read<int>(),y=read<int>();
g[x].push_back(y),g[y].push_back(x);
}
for(int i=1;i<=n;++i)
read(w[i]);
dfs1(1,0),dfs2(1,1);
T::build(1,1,n);
int q=read<int>();
char cmd[10];
while(q--){
scanf("%s",cmd);
if(cmd[1]=='H'){
int x=read<int>(),v=read<int>();
modify(x,v);
}
else if(cmd[1]=='M'){
int x=read<int>(),y=read<int>();
printf("%d\n",major(x,y));
}
else{
int x=read<int>(),y=read<int>();
printf("%d\n",summation(x,y));
}
}
return 0;
}

LG2590 [ZJOI2008]树的统计的更多相关文章

  1. BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14302  Solved: 5779[Submit ...

  2. bzoj1036 [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 12646  Solved: 5085 [Subm ...

  3. BZOJ 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 14354  Solved: 5802 [Subm ...

  4. 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分

    [BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...

  5. bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 10677  Solved: 4313[Submit ...

  6. Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 11102  Solved: 4490[Submit ...

  7. 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 12266  Solved: 4945[Submit ...

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

    树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...

  9. 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 7496  Solved: 3078[Submit] ...

随机推荐

  1. 《Think in Java》(十四)类型信息

    简介 RTTI,RunTime Type Information,运行时类型信息.Java 在运行时识别对象和类的信息主要有两种方式:一种是"传统的"RTTI,它假定我们在编译时已 ...

  2. HDU 4352 XHXJ's LIS ★(数位DP)

    题意 求区间[L,R]内满足各位数构成的数列的最长上升子序列长度为K的数的个数. 思路 一开始的思路是枚举数位,最后判断LIS长度.但是这样的话需要全局数组存枚举的各位数字,同时dp数组的区间唯一性也 ...

  3. hapRroxy 安装配置详解

    简介 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案. HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要 ...

  4. ansible入门六(roles)

    一.什么场景下会用roles? 假如我们现在有3个被管理主机,第一个要配置成httpd,第二个要配置成php服务器,第三个要配置成MySQL服务器.我们如何来定义playbook? 第一个play用到 ...

  5. LoadBalancerv2的原理分析

    OpenStack 是直接采用各种开源可用的负载均衡项目来完成负载均衡的任务,默认使用 HAProxy.LBaaSv2 本质来说,其实也是根据用户提出的负载均衡要求,生成符合的HAProxy配置文件并 ...

  6. 十六、dbms_space_admin(提供了局部管理表空间的功能)

    1.概述 作用:提供了局部管理表空间的功能 2.包的组成 1).segment_verify作用:用于检查段的区映像是否与位图一致语法:dbms_space_admin.segment_verify( ...

  7. ViewBag、ViewData、TempData之间的区别

    1.ViewBag and ViewData(非跨视图访问) 1)ViewBag是一种dynamic动态类型,用户可以自定义属性并为其赋值,它会在运行时动态解析(例:可以作为变量.数组等各种对象传递并 ...

  8. hdu 6038 Function

    Function Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  9. Java基础学习-常见API

    package commonAPIs; /*java.lang 类 Object java.lang.Object public class Object类 Object 是类层次结构的根类.每个类都 ...

  10. TensorFlow 的使用步骤

    使用 TensorFlow 的基本步骤 学习目标: 学习基本的 TensorFlow 概念 在 TensorFlow 中使用 LinearRegressor 类并基于单个输入特征预测各城市街区的房屋价 ...