[ZJOI2008]树的统计-树链剖分
#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]树的统计-树链剖分的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count-树链剖分(点权)(单点更新、路径节点最值、路径求和)模板,超级认真写了注释啊啊啊
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 23015 Solved: 9336[Submit ...
- 树的统计Count---树链剖分
NEFU专项训练十和十一——树链剖分 Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t ...
- BZOJ1036[ZJOI2008]树的统计——树链剖分+线段树
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...
- [ZJOI2008]树的统计——树链剖分
本题是一个树链剖分裸题,由于比较菜,老是RE,后来发现是因为使用了全局变量. /************************************************************ ...
- [luogu P2590 ZJOI2008] 树的统计 (树链剖分)
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- luoguP2590 [ZJOI2008]树的统计(树链剖分)
luogu P2590 [ZJOI2008]树的统计 题目 #include<iostream> #include<cstdlib> #include<cstdio> ...
- 洛谷P2590 [ZJOI2008] 树的统计 [树链剖分]
题目传送门 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t ...
- BZOJ 1036 树的统计-树链剖分
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...
- BZOJ-1036 树的统计Count 链剖线段树(模板)=(树链剖分+线段树)
潇爷昨天刚刚讲完...感觉得还可以...对着模板打了个模板...还是不喜欢用指针.... 1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Lim ...
- bzoj1036 树的统计 树链剖分模板
题意:给出树上任意两点,求路径上的值的和与最大值,带单点修改操作 树链剖分思路: 1.对树进行dfs求出点的深度和父亲节点,然后求出轻重儿子(重儿子就是点最多的那个子树,其余都是轻儿子),用一个son ...
随机推荐
- split函数用法
split函数详解 split翻译为分裂. split()就是将一个字符串分裂成多个字符串组成的列表. split()当不带参数时以空格进行分割,当代参数时,以该参数进行分割. //---当不带 ...
- 【原创】讲讲亿级PV的负载均衡架构
引言 本来没想写这个题材的,为了某某童鞋能够更好的茁壮成长,临时写一篇负载均衡的.负载均衡,大家可能听过什么3层负载均衡.4层负载均衡.7层负载均衡什么的?那这是怎么分的呢,ok,是根据osi七层网络 ...
- Mysql_安装
安装环境:win7 1.下载zip安装包: MySQL8.0 For Windows zip包下载地址:https://dev.mysql.com/downloads/file/?id=476233, ...
- 爬虫之BS&Xpath
BeautifulSoup 一 简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: ''' Beautiful Soup提供一些简单的.p ...
- Winform数据库连接app.config文件配置
1.添加配置文件 新建一个winform应用程序,类似webfrom下有个web.config,winform下也有个App.config;不过 App.config不是自动生成的需要手动添加,鼠标右 ...
- Grovvy带参数的闭包
定义带参数的闭包:
- mybatis中使用到的设计模式
Mybatis中使用到了哪些设计模式呢?下面就简单的来介绍下: 1.构造者模式: 构造者模式是在mybatis初始化mapper映射文件的过程中,为<cache>节点创建Cache对象的方 ...
- SpringMVC学习手册(三)------EL和JSTL(上)
1.含义 EL: Expression Language , 表达式语言 JSTL: Java Server Pages Standard Tag Library, JSP标准标签库 ...
- python之常用模块一(time、random、os、sys)
摘要:时间模块time .随机模块random .os模块.sys模块 一.时间模块 三种格式 时间戳时间:浮点数 单位为秒 时间戳起始时间: 1970.1.1 0:0:0 英国伦敦时间 1970.1 ...
- 查看Android系统已安装应用的列表
可以通过adb shell pm list package 我们可以通过系统提供的工具pm来隐藏一些应用,比如:pm hide和pm disable pm disable <PACKAGE_OR ...