题目描述 Description

一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。

我们将以下面的形式来要求你对这棵树完成一些操作:

  1. I.                    CHANGE u t : 把结点u的权值改为t
  2. II.                 QMAX u v: 询问从点u到点v的路径上的节点的最大权值
  3. III.               QSUM u v: 询问从点u到点v的路径上的节点的权值和

 

注意:从点u到点v的路径上的节点包括u和v本身

输入描述 Input Description

输入文件的第一行为一个整数n,表示节点的个数。

接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。

       接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。

接下来1行,为一个整数q,表示操作的总数。

接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。

输出描述 Output Description

对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

样例输入 Sample Input

4

1 2

2 3

4 1

4 2 1 3

12

QMAX 3 4

QMAX 3 3

QMAX 3 2

QMAX 2 3

QSUM 3 4

QSUM 2 1

CHANGE 1 5

QMAX 3 4

CHANGE 3 6

QMAX 3 4

QMAX 2 4

QSUM 3 4

样例输出 Sample Output

4

1

2

2

10

6

5

6

5

16

数据范围及提示 Data Size & Hint

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

分类标签 Tags 点此展开

思路:树链剖分搞一下就好。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 30010
using namespace std;
int n,q,sz,tot;
int w[MAXN];
int top[MAXN],id[MAXN];
int to[MAXN*],net[MAXN*],head[MAXN];
int dad[MAXN],size[MAXN],deep[MAXN];
struct nond{
int l,r,max,sum;
}tree[MAXN*];
void add(int u,int v){
to[++tot]=v;net[tot]=head[u];head[u]=tot;
to[++tot]=u;net[tot]=head[v];head[v]=tot;
}
void up(int now){
tree[now].sum=tree[now*].sum+tree[now*+].sum;
tree[now].max=max(tree[now*].max,tree[now*+].max);
}
void build(int now,int l,int r){
tree[now].l=l;tree[now].r=r;
if(tree[now].l==tree[now].r) return ;
int mid=(tree[now].l+tree[now].r)/;
build(now*,l,mid);
build(now*+,mid+,r);
up(now);
}
void change(int now,int pos,int x){
if(tree[now].l==tree[now].r){
tree[now].max=x;tree[now].sum=x;
return ;
}
int mid=(tree[now].l+tree[now].r)/;
if(pos<=mid) change(now*,pos,x);
else if(pos>mid) change(now*+,pos,x);
up(now);
}
int query(int now,int l,int r,int k){
if(tree[now].l==l&&tree[now].r==r){
if(k==) return tree[now].max;
else if(k==) return tree[now].sum;
}
int mid=(tree[now].l+tree[now].r)/;
if(r<=mid) return query(now*,l,r,k);
else if(l>mid) return query(now*+,l,r,k);
else{
if(k==) return max(query(now*,l,mid,k),query(now*+,mid+,r,k));
else if(k==) return query(now*,l,mid,k)+query(now*+,mid+,r,k);
}
}
void dfs(int now){
size[now]=;
deep[now]=deep[dad[now]]+;
for(int i=head[now];i;i=net[i])
if(dad[now]!=to[i]){
dad[to[i]]=now;
dfs(to[i]);
size[now]+=size[to[i]];
}
}
void dfs1(int x){
int t=;id[x]=++sz;
if(!top[x]) top[x]=x;
change(,id[x],w[x]);
for(int i=head[x];i;i=net[i])
if(dad[x]!=to[i]&&size[to[i]]>size[t])
t=to[i];
if(t){
top[t]=top[x];
dfs1(t);
}
for(int i=head[x];i;i=net[i])
if(dad[x]!=to[i]&&t!=to[i])
dfs1(to[i]);
}
int squery(int x,int y,int pos){
int ans;
if(pos==) ans=;
else if(pos==) ans=-0x7f7f7f7f;
for(;top[x]!=top[y];){
if(deep[top[x]]<deep[top[y]]) swap(x,y);
if(pos==) ans+=query(,id[top[x]],id[x],pos);
else if(pos==) ans=max(ans,query(,id[top[x]],id[x],pos));
x=dad[top[x]];
}
if(id[x]>id[y]) swap(x,y);
if(pos==) ans+=query(,id[x],id[y],pos);
else if(pos==) ans=max(ans,query(,id[x],id[y],pos));
return ans;
}
int main(){
scanf("%d",&n);
for(int i=;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
}
for(int i=;i<=n;i++) scanf("%d",&w[i]);
build(,,n);
dfs();
dfs1();
scanf("%d",&q);
for(int i=;i<=q;i++){
char c[];int u,v;
cin>>c;scanf("%d%d",&u,&v);
if(c[]=='C') change(,id[u],v);
else if(c[]=='Q'&&c[]=='M') printf("%d\n",squery(u,v,));
else printf("%d\n",squery(u,v,));
}
}

codevs 2460 树的统计的更多相关文章

  1. 2008ZJOI树的统计

    codevs 2460 树的统计 http://codevs.cn/problem/2460/ 2008年省队选拔赛浙江  题目等级 : 大师 Master   题目描述 Description 一棵 ...

  2. Codevs 2460 == BZOJ 1036 树的统计

     2460 树的统计 2008年省队选拔赛浙江 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 一棵树上有n个节点,编号分别为1 ...

  3. C++之路进阶——codevs2460(树的统计)

    2460 树的统计 2008年省队选拔赛浙江  时间限制: 2 s  空间限制: 128000 KB  题目等级 : 大师 Master       题目描述 Description 一棵树上有n个节 ...

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

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

  5. bzoj1036 [ZJOI2008]树的统计Count

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

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

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

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

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

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

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

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

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

随机推荐

  1. RCF:一个相当不错的C++分布式RPC框架

    RCF(远程调用框架)是一个可以移植的C++进程间通信框架,使用C++语言特性,提供了一个简单高效的编写分布式C++软件的途径.RCF利用编译时多态清晰分开了接口和实现. 和传统的RPC框架如CORB ...

  2. 【Luogu4389】付公主的背包

    题目 传送门 解法 答案显然是\(n\)个形如\(\sum_{i \geq 1} x^{vi}\)的多项式的卷积 然而直接NTT的时间复杂度是\(O(nm\log n)\) 我们可以把每个多项式求\( ...

  3. 2019手机号码JS正则表达式

    前端的正则表达式验证往往是最繁多最复杂的,所以整理了一些最近自己常用的正则表达式,希望能对大家有所帮助! /* 合法uri */ export function validateURL(textval ...

  4. itext 生成pdf文档 小结(自己备忘)

    1.引入maven <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf& ...

  5. shell 实用命令学习

    查找文件 -iname 大小写不敏感 “*.log” .log后缀的文件 -type d 文件类型为目录的 find ./ -name 'index.html' 查找当前目录,及其子目录下文件

  6. Spring 的优秀工具类盘点---转

    第 1 部分: 文件资源操作和 Web 相关工具类 http://www.ibm.com/developerworks/cn/java/j-lo-spring-utils1/ 文件资源操作 文件资源的 ...

  7. 通过Web Service实现IP地址查询功能

    实例01 实现一个简单的Web服务访问 本实例将实现IP地址查询接口服务,根据用户传入的IP地址返回IP所在的省.市.地区,实例中将会用到IP地址库用于查询信息,由于数据较多,所以读者可在光盘资源文件 ...

  8. 用SQL Server验证用户名和密码

    用SQL Server验证用户名和密码,从页面输入的用户名和密码与数据库的用户名和密码进行匹配,正确则登入,错误则提醒. <form action="index.jsp" m ...

  9. iproute2常用命令

    #常用命令 ip link show #显示链路 ip addr show #显示地址(或ifconfig) ip route show #显示路由(route -n) ip neigh show # ...

  10. (转)openlayers实现在线编辑

    http://blog.csdn.net/gisshixisheng/article/details/46054949 概述: 在前面有篇博文讲述了基于Arcgis for js和wkt实现在线数据的 ...