题目描述 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. 使用 Swift 3.0 操控日期

    作者:Joe,原文链接,原文日期:2016-09-20译者:Cwift:校对:walkingway:定稿:CMB 当你在想要 大规模重命名 时,一个附带的挑战就是要确保所有相关的文档都必须同步更新.比 ...

  2. B1295 [SCOI2009]最长距离 最短路

    就是一道最短路的裸题,直接跑spfa就行了.(spfa死了) 最后在答案处判断是否障碍物太多,然后就直接找最大值就行. (数据特别水,我错误算法60) 题干: Description windy有一块 ...

  3. [SpringMVC]定义多个前缀映射的问题

    转自:https://penciltim.iteye.com/blog/501073 我在web.xml里面定义多个dispatch-servlet的前缀映射,像下面这样 <!-- Servle ...

  4. JavaScript 获取星期几函数

    function getDayofWeek() {            var day = "";            var time = new Date();       ...

  5. 10.Flask-上下文

    1.1.local线程隔离对象 不用local对象的情况 from threading import Thread request = ' class MyThread(Thread): def ru ...

  6. java热部署

    最近使用java做项目,研究了一下热部署,能够提高工作效率. 需要准备的工具: 1.安装文件http://update.zeroturnaround.com/update-site/ 2.破解 下载破 ...

  7. Entity Framework Code First -- 延迟加载和预先加载

    还是以这两个表为例子 country包含零个或多个city, 这个外键关系是我后来加上去,原来没有. 然后再用Power Tool逆向, 产生如下代码 1: using System.Componen ...

  8. javascript中执行环境和作用域(js高程)

    执行环境(execution context,为简单起见,有时也成为“环境”)是javascript中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境 ...

  9. Android几种常见的多渠道(批量)打包方式介绍

    多渠道打包,主要是为了统计不同的渠道上包的下载数量,渠道越多,我们需要打的包数量越多,这个时候,我们没法去使用单纯的手动打包去一个一个的生成不同的渠道包,我们需要更高效的打包方式. 声明渠道方式一: ...

  10. android学习-第二讲(修改项目名称和图标,log,过滤器)

    一.在app/src/main/res下有 AndroidManifest.xml打开,打开后如下图1 二.日志工具log log.v()  log.d()  log.i()  log.w()  lo ...