#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. 聊聊计算机中的编码(Unicode,GBK,ASCII,utf8,utf16,ISO8859-1等)以及乱码问题的解决办法

    作为一个程序员,一个中国的程序员,想来“乱码”问题基本上都遇到过,也为之头疼过.出现乱码问题的根本原因是编码与解码使用了不同而且不兼容的“标准”,在国内一般出现在中文的编解码过程中. 我们平时常见的编 ...

  2. Sql Server2008如何让外网访问自己的数据库

    1.打开 Sql Server配置管理器 2.修改Sql Server网络配置,将Tcp/IP协议修改为“已启用” 3.重启Sql Server服务即可(如果不知道怎么重启Sql Server服务,重 ...

  3. 2 数据分析之Numpy模块(1)

    Numpy Numpy(Numerical Python的简称)是高性能科学计算和数据分析的基础包.它是我们课程所介绍的其他高级工具的构建基础. 其部分功能如下: ndarray, 一个具有复杂广播能 ...

  4. h5-canvas 像素操作

    ###1.得到场景像素数据 getImageData():获得一个包含画布场景像素数据的ImageData对象,它代表了画布区域的对象数据 ctx.getImageData(sx,sy,sw,sh) ...

  5. 8 ServletContext

    1 为什么需要ServletContext 技术 显示网站多少人在线,显示当前登录者是第几位登录者等信息. 2 什么是ServletContext 可以把它想象成一个服务器上的公共空间,每个用户都可以 ...

  6. java从Swagger Api接口获取数据工具类

  7. vue 拖拽移动(类似于iPhone虚拟home )

    vue 移动端 PC 兼容 元素 拖拽移动  效果演示 事件知识点 移动端 PC端 注释 touchstart mousedown 鼠标/手指按下事件 touchmove mousemove 鼠标/手 ...

  8. js身份证正则

    身份证正则 var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/; if (!reg.test(IDCard)) {return false;}

  9. DataTable转list时 可空类型的转换问题

    public class UtilHelper { public static IList<T> ConvertTo<T>(DataTable table) { if (tab ...

  10. Red Hat Enterprise Linux AS4, C++ OCCI connect Oracle 9i

    前提是已经安装好Oracle 9i. 1. 下载对应的ORACLE client安装. http://www.oracle.com/technetwork/database/features/inst ...