BZOJ1036[ZJOI2008]树的统计Count 题解
题目大意:
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。有一些操作:1.把结点u的权值改为t;2.询问从点u到点v的路径上的节点的最大权值 3.询问从点u到点v的路径上的节点的权值和。
思路:
进行轻重树链剖分,再根据每个节点的dfs序建立线段树,维护其最大值以及和,询问时用树剖后的结果将重链作为区间一段一段求和。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#define M 1000009
using namespace std; int n,dfn,cnt,to[M],next[M],head[M],size[M],vis[M],deep[M],fa[M],top[M],w[M],mx[M],sum[M],id[M]; void add(int x,int y)
{
to[++cnt]=y,next[cnt]=head[x],head[x]=cnt;
} void dfs1(int x)
{
size[x]=vis[x]=;
for (int i=head[x];i;i=next[i])
if (!vis[to[i]])
{
deep[to[i]]=deep[x]+;
fa[to[i]]=x;
dfs1(to[i]);
size[x]+=size[to[i]];
}
} void dfs2(int x,int chain)
{
int k=,i;
id[x]=++dfn;
top[x]=chain;
for (i=head[x];i;i=next[i])
if (deep[to[i]]>deep[x] && size[to[i]]>size[k]) k=to[i];
if (!k) return;
dfs2(k,chain);
for (i=head[x];i;i=next[i])
if (deep[to[i]]>deep[x] && to[i]!=k) dfs2(to[i],to[i]);
} int LCA(int x,int y)
{
for (;top[x]!=top[y];x=fa[top[x]])
if (deep[top[x]]<deep[top[y]]) swap(x,y);
return deep[x]<deep[y]?x:y;
} void change(int l,int r,int x,int y,int cur)
{
if (l==r)
{
mx[cur]=sum[cur]=y;
return;
}
int mid=l+r>>;
if (x<=mid) change(l,mid,x,y,cur<<);
else change(mid+,r,x,y,cur<<|);
mx[cur]=max(mx[cur<<],mx[cur<<|]);
sum[cur]=sum[cur<<]+sum[cur<<|];
} int SUM(int L,int R,int l,int r,int cur)
{
if (l<=L && r>=R) return sum[cur];
int mid=L+R>>;
if (l>mid) return SUM(mid+,R,l,r,cur<<|);
else if (r<=mid) return SUM(L,mid,l,r,cur<<);
else return SUM(L,mid,l,r,cur<<)+SUM(mid+,R,mid+,r,cur<<|);
} int MAX(int L,int R,int l,int r,int cur)
{
if (l<=L && r>=R) return mx[cur];
int mid=L+R>>;
if (l>mid) return MAX(mid+,R,l,r,cur<<|);
else if (r<=mid) return MAX(L,mid,l,r,cur<<);
else return max(MAX(L,mid,l,mid,cur<<),MAX(mid+,R,mid+,r,cur<<|));
} int Sum(int x,int y)
{
int ans=;
for (;top[x]!=top[y];x=fa[top[x]])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
ans+=SUM(,n,id[top[x]],id[x],);
}
if (deep[x]>deep[y]) swap(x,y);
return ans+SUM(,n,id[x],id[y],);
} int Max(int x,int y)
{
int ans=-;
for (;top[x]!=top[y];x=fa[top[x]])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
ans=max(ans,MAX(,n,id[top[x]],id[x],));
}
if (deep[x]>deep[y]) swap(x,y);
return max(ans,MAX(,n,id[x],id[y],));
} int main()
{
int m,i,x,y;
scanf("%d",&n);
for (i=;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
dfs1();
dfs2(,);
for (i=;i<=n;i++) scanf("%d",&w[i]),change(,n,id[i],w[i],);
scanf("%d",&m);
for (i=;i<=m;i++)
{
char ch[];
scanf("%s%d%d",ch,&x,&y);
if (ch[]=='C') w[x]=y,change(,n,id[x],y,);
else
if (ch[]=='S') printf("%d\n",Sum(x,y));
else printf("%d\n",Max(x,y));
}
return ;
}
BZOJ1036[ZJOI2008]树的统计Count 题解的更多相关文章
- [BZOJ1036][ZJOI2008]树的统计Count 解题报告|树链剖分
树链剖分 简单来说就是数据结构在树上的应用.常用的为线段树splay等.(可现在splay还不会敲囧) 重链剖分: 将树上的边分成轻链和重链. 重边为每个节点到它子树最大的儿子的边,其余为轻边. 设( ...
- bzoj1036 [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 12646 Solved: 5085 [Subm ...
- bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题
[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...
- bzoj千题计划124:bzoj1036: [ZJOI2008]树的统计Count
http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分板子题 #include<cstdio> #include<iost ...
- BZOJ1036 [ZJOI2008]树的统计Count 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1036 题意概括 一个树,每个节点有一个权值.3种操作. 1:修改某一个节点的权值. 2:询问某两个 ...
- 【lct】bzoj1036 [ZJOI2008]树的统计Count
题意:给你一棵树,点带权,支持三种操作:单点修改:询问链上和:询问链上max. 这里的Query操作用了与上一题不太一样的做法(上一题用那种做法,因为在边带权的情况下换根太困难啦): 先ChangeR ...
- bzoj1036 zjoi2008 树的统计 count
填坑= =第一道裸树剖 #include<cstdio> #include<algorithm> #include<cstring> #include<cst ...
- [BZOJ1036] [ZJOI2008] 树的统计Count (LCT)
Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...
- bzoj1036 [ZJOI2008]树的统计Count(树链剖分)
Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...
随机推荐
- Lattice 的 Framebuffer IP核使用调试笔记之datasheet笔记
本文由远航路上ing 原创,转载请标明出处. 学习使用以及调试Framebuffer IP 核已经有一段时间了,调试的时候总想记录些东西,可是忙的时候就没有时间来写,只有先找个地方记录下,以后再总结. ...
- ODATA WEB API(一)---扩展使用
一.概述 时间也算充足,抽点时间总结下OData的常用的使用方式,开放数据协议(OData)是一个查询和更新数据的Web协议.OData应用了web技术如HTTP.Atom发布协议(AtomPub)和 ...
- ytu 1067: 顺序排号(约瑟夫环)
1067: 顺序排号 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 31 Solved: 16[Submit][Status][Web Board] ...
- poj 1003:Hangover(水题,数学模拟)
Hangover Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 99450 Accepted: 48213 Descri ...
- 攻城狮在路上(肆)How tomcat works(一) 简单的web服务器
该节总共三个类:Request\Response\HttpServer---user.dir 该节的目的是实现简单web服务器对静态文件的访问.需要对请求头.请求体的格式有所了解,不然就没有 ...
- 攻城狮在路上(壹) Hibernate(五)--- 映射一对多关联关系
关联是有方向的,包含单向关联和双向关联.分别讨论.本文以客户Customer和订单Order来进行讨论:一个Customer有多个Order,每个Order对应一个Customer. Customer ...
- 第二十篇:在SOUI中使用分层窗口
从Windows 2K开始,MS为UI开发引入了分层窗口这一窗口风格.使用分层窗口,应用程序的主窗口可以是半透明,也可以是逐点半透明(即每一个像素点的透明度可以不同). 可以说,正是因为有了分层窗口, ...
- windows 2003 企业版 下载地址+序列号
迅雷地址: thunder://QUFodHRwOi8vcy5zYWZlNS5jb20vV2luZG93c1NlcnZlcjIwMDNTUDJFbnRlcnByaXNlRWRpdGlvbi5pc29a ...
- Sypder上手
准备用python来做数据分析,选择了Sypder 刚打开时有点蒙逼,工作目录直接就在C盘了,想切换一下,发现右边工具栏里有工程路径,发现原来默认是在c盘用户路径下创建了一个临时工程 于是直接菜单栏/ ...
- CF731C Socks并查集(森林),连边,贪心,森林遍历方式,动态开点释放内存
http://codeforces.com/problemset/problem/731/C 这个题的题意是..小明的妈妈给小明留下了n只袜子,给你一个大小为n的颜色序列c 代表第i只袜子的颜色,小明 ...