#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+5;
#define mid ((l+r)>>1)
#define left_son root<<1,l,mid
#define right_son root<<1|1,mid+1,r
int n,m;
int e,begin[maxn],next[maxn],to[maxn],w[maxn],a[maxn];
struct segment_tree{
int sum,l,r,mark,maxw;
}tree[maxn<<2];
int son[maxn],id[maxn],father[maxn],cnt,deep[maxn],size[maxn],top[maxn],_map[maxn];
inline void add(int x,int y){
to[++e] = y;
next[e] = begin[x];
begin[x] = e;
}
inline void pushup(int root){
tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum;
tree[root].maxw = max(tree[root<<1].maxw,tree[root<<1|1].maxw);
}
inline void build(int root,int l,int r){
tree[root].l = l;
tree[root].r = r;
tree[root].mark = 0;
if(l == r){
tree[root].sum = w[_map[l]];
tree[root].maxw = w[_map[l]];
return;
}
build(left_son);
build(right_son);
pushup(root);
}
inline void update(int root,int l,int r,int num,int k){
if(l == r){
tree[root].sum = k;
tree[root].maxw = k;
return;
}
if(num <= mid)update(left_son,num,k);
else update(right_son,num,k);
pushup(root);
}
inline int query(int root,int l,int r,int al,int ar){
if(al > r || ar < l)return 0;
if(al <= l && ar >= r)return tree[root].sum;
return query(left_son,al,ar)+query(right_son,al,ar);
}
inline int query_max_node(int root,int l,int r,int al,int ar){
if(al > r || ar < l)return -999999999;
if(al <= l && ar >= r)return tree[root].maxw;
return max(query_max_node(left_son,al,ar),query_max_node(right_son,al,ar));
}
inline int query_range(int x,int y){
int ans = 0;
while(top[x] != top[y]){
if(deep[top[x]] < deep[top[y]])swap(x,y);
ans += query(1,1,cnt,id[top[x]],id[x]);
x = father[top[x]];
}
if(deep[x] > deep[y])swap(x,y);
ans += query(1,1,cnt,id[x],id[y]);
return ans;
}
inline int query_max_range(int x,int y){
int ans = -999999999;
while(top[x] != top[y]){
if(deep[top[x]] < deep[top[y]])swap(x,y);
ans = max(ans,query_max_node(1,1,cnt,id[top[x]],id[x]));
x = father[top[x]];
}
if(deep[x] > deep[y])swap(x,y);
ans = max(ans,query_max_node(1,1,cnt,id[x],id[y]));
return ans;
}
inline void dfs1(int x,int fa,int dep){
deep[x] = dep;
father[x] = fa;
size[x] = 1;
int maxson = -999999999;
for(int i = begin[x];i;i = next[i]){
int y = to[i];
if(y == fa)continue;
dfs1(y,x,dep+1);
size[x] += size[y];
if(size[y] > maxson)son[x] = y,maxson = size[y];
}
}
inline void dfs2(int x,int ntop){
id[x] = ++cnt;
top[x] = ntop;
_map[id[x]] = x;
if(!son[x])return;
dfs2(son[x],ntop);
for(int i = begin[x];i;i = next[i]){
int y = to[i];
if(y == father[x] || y == son[x])continue;
dfs2(y,y);
}
}
int main(){
cin>>n;
for(int i = 1,u,v;i < n;i++){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i = 1;i <= n;i++)scanf("%d",&w[i]);
dfs1(1,0,1);
dfs2(1,1);
build(1,1,n);
cin>>m;
while(m--){
string ask;
int u,v;
cin>>ask>>u>>v;
if(ask == "CHANGE")update(1,1,cnt,id[u],v);
if(ask == "QMAX")printf("%d\n",query_max_range(u,v));
if(ask == "QSUM")printf("%d\n",query_range(u,v));
}
return 0;
}

  

[ZJOI2008]树的统计-树链剖分的更多相关文章

  1. BZOJ 1036: [ZJOI2008]树的统计Count-树链剖分(点权)(单点更新、路径节点最值、路径求和)模板,超级认真写了注释啊啊啊

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

  2. 树的统计Count---树链剖分

    NEFU专项训练十和十一——树链剖分 Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t ...

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

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

  4. [ZJOI2008]树的统计——树链剖分

    本题是一个树链剖分裸题,由于比较菜,老是RE,后来发现是因为使用了全局变量. /************************************************************ ...

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

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

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

    luogu P2590 [ZJOI2008]树的统计 题目 #include<iostream> #include<cstdlib> #include<cstdio> ...

  7. 洛谷P2590 [ZJOI2008] 树的统计 [树链剖分]

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

  8. BZOJ 1036 树的统计-树链剖分

    [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...

  9. BZOJ-1036 树的统计Count 链剖线段树(模板)=(树链剖分+线段树)

    潇爷昨天刚刚讲完...感觉得还可以...对着模板打了个模板...还是不喜欢用指针.... 1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Lim ...

  10. bzoj1036 树的统计 树链剖分模板

    题意:给出树上任意两点,求路径上的值的和与最大值,带单点修改操作 树链剖分思路: 1.对树进行dfs求出点的深度和父亲节点,然后求出轻重儿子(重儿子就是点最多的那个子树,其余都是轻儿子),用一个son ...

随机推荐

  1. Activiti开发案例之activiti-app更换数据源

    前言 由于Activiti 默认使用的数据库是H2数据库,重启服务后相关数据会丢失.为了永久保存,所以要配置关系型数据库,这里我们选择 SqlServer ,有钱任性. 环境 Activiti6,Sq ...

  2. go语言-值类型与引用类型

    https://www.cnblogs.com/java-zhao/p/9942311.html https://blog.csdn.net/TDCQZD/article/details/826836 ...

  3. jquery动态设置图片路径和超链接href属性

    js document.getElementById("myImage").src="hackanm.gif"; jquery $("#img&quo ...

  4. 关于B树B+树的详细解释——绝对精彩

    B树是一种完全平衡树,B+树是B树的升级版,使用更多.B树和B+树存在的目的是如何提高磁盘文件的访问(如数据库)效率. 关于B树和B+树的一篇比较好的文章: https://www.cnblogs.c ...

  5. [第二届构建之法论坛] 预培训文档(C++版)

    本博客是第二届构建之法论坛暨软件工程培训活动预培训文档中[适用于结对编程部分的C++版本],需要实验者有一部分C++基础. 目录 Part0.背景 Part1.配置环境 Part2.克隆项目 Part ...

  6. sqlalchemy常用

    一.SQLAlchemy 创建表 from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Colu ...

  7. JEECG 3.8宅男优化版本发布

    1024程序员节宅男节日快乐 -- JAVA快速开发平台,JEECG 3.8宅男优化版本发布 - JEECG开源社区 - CSDN博客https://blog.csdn.net/zhangdaisco ...

  8. JAVA多线程-实现同步

    一.什么是线程安全问题 当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题.但是做读操作是不会发生数据冲突问题. 二.如何解决线程安全问题 1)如何 ...

  9. Java的clone():深复制与浅复制

    Java中要想自定义类的对象可以被复制,自定义类就必须实现Cloneable中的clone()方法,如下: public class Student implements Cloneable { pr ...

  10. git安装和GitHub使用

    一.git安装 1.git下载 https://github.com/git-for-windows/git/releases/tag/v2.17.1.windows.2 在如上地址下载git,并安装 ...