LG2590 [ZJOI2008]树的统计
题意
一棵树上有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]树的统计的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- bzoj1036 [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 12646 Solved: 5085 [Subm ...
- BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 14354 Solved: 5802 [Subm ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10677 Solved: 4313[Submit ...
- Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 11102 Solved: 4490[Submit ...
- 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12266 Solved: 4945[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...
- 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 7496 Solved: 3078[Submit] ...
随机推荐
- ItemsControl控件-----常用的
常用的ItemsControl控件有:ListBox.ComboBox.TreeView.DataGrid等等.(小结:均是“多项”控件,多项 对应 集合,单项 对应 元素) ItemsControl ...
- 1-10 RHLE7 系统进程管理
1.1-Linux进程管理 程序.进程.线程 程序:一组指令的集合 QQ 进程:程序的执行就是进程.也可以把进程看成一个独立的程序,在内存中有其对应的代码空间和数据空间,一个进程所拥有的数据和代 ...
- Lua学习笔记1,基本数据类型
1.字符串的连接使用的是 .. ,如 print(123 .. 44) 输出 12344 print ('a' .. 'b') 输出 ab print(123 .. 44)这句的时候 .. 两边要空 ...
- tcpdump 使用实例
详细的文档见tcpdump高级过滤技巧 基本语法 ========过滤主机--------- 抓取所有经过 eth1,目的或源地址是 192.168.1.1 的网络数据# tcpdump -i eth ...
- python2 commands模块在python3.x被subprocess取代
subprocess 可以执行shell命令的相关模块和函数有: os.systemos.spawnos.popen --废弃popen2.* --废弃commands.* --废弃,3.x中被移除 ...
- 使用C++为对象分配与释放内存时的几个好习惯
本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/ 最近在为公司的项目写内存泄漏定位工具,遇到一些关于C++构造与析构对象的问题,在此记录一下 ...
- 027——VUE中事件修饰符:stop prevent self capture
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- C++复习6.C/C++高级数据类型
C/C++高级数据类型 1.C语言支持把基本数据类型组合起来形成更加强大的构造数据类型,就是C语言的struct(UDT, User Defined Type). Struct 和class : 在C ...
- js常用正则表达式,滚蛋吧!你们测试组bug,让你挑
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- django-pymysql-封装的sql使用
封装的sql import pymysql def get_list(sql,args): conn = pymysql.connect(host=, user='root', passwd='', ...