题目描述 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之间。

树链剖分基础题。顺便练一练线段树,这一回又加深了对线段树的理解。

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef long long LL;
#define mem(a,b) memset(a,b,sizeof(a))
typedef pair<int,int> PII;
inline int read()
{
int x=,f=;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)){x=x*+c-'';c=getchar();}
return x*f;
}
const int maxn=,oo=;
struct Edge
{
int u,v,next;
Edge() {}
Edge(int _1,int _2,int _3): u(_1),v(_2),next(_3) {}
}e[*maxn];
int n,ce=-,m,a,b,first[maxn],sum[*maxn],Max[*maxn],w[maxn],pa[maxn],deep[maxn],size[maxn],id[maxn],es,bl[maxn];
char s[];
void addEdge(int a,int b)
{
e[++ce]=Edge(a,b,first[a]);first[a]=ce;
e[++ce]=Edge(b,a,first[b]);first[b]=ce;
}
void dfs(int now,int fa)
{
size[now]=;
for(int i=first[now];i!=-;i=e[i].next)
{
if(e[i].v==fa)continue;
deep[e[i].v]=deep[now]+;
pa[e[i].v]=now;
dfs(e[i].v,now);
size[now]+=size[e[i].v];
}
}
void divide(int now,int chain)
{
int maxs=;
id[now]=++es;bl[now]=chain;
for(int i=first[now];i!=-;i=e[i].next)
if(pa[e[i].v]!=now && size[e[i].v]>size[maxs])maxs=e[i].v;
if(!maxs)return;
divide(maxs,chain);
for(int i=first[now];i!=-;i=e[i].next)
if(pa[e[i].v]!=now && e[i].v!=maxs)divide(e[i].v,e[i].v);
}
void build(int l,int r,int o)
{
if(l==r){sum[o]=Max[o]=w[l];return;}
int mid=(l+r)>>,lo=o<<,ro=lo|;
build(l,mid,lo);build(mid+,r,ro);
sum[o]=sum[lo]+sum[ro];
Max[o]=max(Max[lo],Max[ro]);
}
int query1(int l,int r,int o,int a,int b)
{
int mid=(l+r)>>,lo=o<<,ro=lo|;
if(l==a && r==b)return sum[o];
if(b<=mid)return query1(l,mid,lo,a,b);
else if(a>mid)return query1(mid+,r,ro,a,b);
else return query1(l,mid,lo,a,mid)+query1(mid+,r,ro,mid+,b);
}
int query2(int l,int r,int o,int a,int b)
{
int mid=(l+r)>>,lo=o<<,ro=lo|;
if(l==a && r==b)return Max[o];
if(b<=mid)return query2(l,mid,lo,a,b);
else if(a>mid)return query2(mid+,r,ro,a,b);
else return max(query2(l,mid,lo,a,mid),query2(mid+,r,ro,mid+,b));
}
void update(int l,int r,int o,int a,int b)
{
if(l==r){sum[o]=Max[o]=b;return;}
int mid=(l+r)>>,lo=o<<,ro=lo|;
if(a<=mid)update(l,mid,lo,a,b);
else update(mid+,r,ro,a,b);
sum[o]=sum[lo]+sum[ro];
Max[o]=max(Max[lo],Max[ro]);
}
int query(int a,int b,int tp)
{
int ans= tp ? : -oo;
while(bl[a]!=bl[b])
{
if(deep[bl[a]]<deep[bl[b]])swap(a,b);
if(tp)ans+=query1(,n,,id[bl[a]],id[a]);
else ans=max(ans,query2(,n,,id[bl[a]],id[a]));
a=pa[bl[a]];
}
if(id[a]>id[b])swap(a,b);
if(tp)ans+=query1(,n,,id[a],id[b]);
else ans=max(ans,query2(,n,,id[a],id[b]));
return ans;
}
int main()
{
mem(first,-);
n=read();
for(int i=;i<n;i++)
{
a=read();b=read();
addEdge(a,b);
}
dfs(,);divide(,);
for(int i=;i<=n;i++)w[id[i]]=read();
build(,n,);m=read();
while(m--)
{
scanf("%s",s);a=read();b=read();
if(s[]=='M')printf("%d\n",query(a,b,));
else if(s[]=='S')printf("%d\n",query(a,b,));
else if(s[]=='H')update(,n,,id[a],b);
}
return ;
}

[codevs2460]树的统计的更多相关文章

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

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

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

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

  3. bzoj1036 [ZJOI2008]树的统计Count

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

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

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

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

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

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

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

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

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

  8. BZOJ_1036_[ZJOI2008]_树的统计Conut_(树链剖分)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1036 给出一棵树以及各点的权值,对数进行如下三种操作: 1.改变某一节点u的值为t; 2.求节 ...

  9. bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

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

随机推荐

  1. 面试官:”准备用HashMap存1w条数据,构造时传10000会触发扩容吗?“

    通常在初始化 HashMap 时,初始容量都是根据业务来的,而不会是一个固定值,为此我们需要有一个特殊处理的方式,就是将预期的初始容量,再除以 HashMap 的装载因子,默认时就是除以 0.75. ...

  2. mysql 基本操作 四

    1.临时表 当绘画结束时,临时表会自动销毁,无法用show tables 查看 临时表. MariaDB [jason]> create temporary table tmp(pro ),ci ...

  3. Github配置SSH密钥

    设置SSH Key Github上连接已有仓库时的认证,是通过使用SSH的公开密钥 在终端terminal中输入 ssh-keygen 该命令的含义是 generate ssh key, 然后一直按回 ...

  4. redis 清除minerd进程的方法

    redis 清除minerd进程的方法 1 修改redis配置文件 //禁止高危命令rename-command FLUSHALL ""rename-command CONFIG ...

  5. [转帖]PostgreSQL的时间/日期函数使用

    PostgreSQL的时间/日期函数使用 https://www.cnblogs.com/mchina/archive/2013/04/15/3010418.html 这个博客的 文章目录比上一个好十 ...

  6. THUSC2019去不了记

    因为泥萌都去SC了,就我在学校里考水考模拟,所以这就变成了水考模拟游记了 Day1 早上本来要到教室早读,发现教室被由年级前\(100\)的非竞赛生的dalao给占据了,发现聪聪在里面,于是进去愉快的 ...

  7. logstash 对配置文件conf敏感信息,密码等加密

    logstash的配置文件conf经常会涉及敏感信息,比如ES,mysql的账户密码等,以下使用logstash导入mysql为例子,加密隐藏mysql的密码. 在向keystore中添加key及其s ...

  8. Kafka学习笔记2--Kafka的服务端配置

    下载解压 kafka 后,在 kafka/config 下有 3 个配置文件与主题的生产.消费相关. server.properties--服务端配置 producer.properties--生产端 ...

  9. 「福利」Java Swing 编写的可视化算法工程,包含树、图和排序

    之前在整理<学习排序算法,结合这个方法太容易理解了>这篇文章时,发现了一个用 Java Swing 编写的可视化算法工程,真心不错!包含了常用数据结构和算法的动态演示,先来张图感受下: 可 ...

  10. .NetCore打包docker镜像

    1..NetCore 项目打包成Docker 镜像 1.1创建一个.NetCore web项目 项目名为   testmvc  此处用的是.NetCore2.1版本 1.2并且在program里面设置 ...