欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ1036


题意概括

  一个树,每个节点有一个权值。3种操作。

  1:修改某一个节点的权值。

  2:询问某两个节点间的权值和

  3:询问某两个节点之间的最大权值。


题解

  树链剖分裸题


代码

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N=30005,Inf=33333;
struct Edge{
int cnt,y[N*2],nxt[N*2],fst[N];
void clear(){
cnt=0;
memset(fst,0,sizeof fst);
}
void add(int a,int b){
y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt;
}
}g;
int n,m,v[N],fa[N],size[N],son[N],depth[N],top[N],p[N],ap[N],cnp;
struct Tree{
int m,s;
}t[N*4];
void Get_Gen_Info(int rt,int pre,int d){
depth[rt]=d,size[rt]=1,fa[rt]=pre,son[rt]=-1;
for (int i=g.fst[rt];i;i=g.nxt[i])
if (g.y[i]!=pre){
int s=g.y[i];
Get_Gen_Info(s,rt,d+1);
size[rt]+=size[s];
if (son[rt]==-1||size[s]>size[son[rt]])
son[rt]=s;
}
}
void Get_Pos(int rt,int tp){
top[rt]=tp,p[rt]=++cnp,ap[cnp]=rt;
if (son[rt]==-1)
return;
else
Get_Pos(son[rt],tp);
for (int i=g.fst[rt];i;i=g.nxt[i]){
int s=g.y[i];
if (s!=fa[rt]&&s!=son[rt])
Get_Pos(s,s);
}
}
void pushup(int rt){
int ls=rt<<1,rs=ls|1;
t[rt].m=max(t[ls].m,t[rs].m);
t[rt].s=t[ls].s+t[rs].s;
}
void build(int rt,int le,int ri){
if (le==ri){
t[rt].m=t[rt].s=v[ap[le]];
return;
}
int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
build(ls,le,mid);
build(rs,mid+1,ri);
pushup(rt);
}
void change(int rt,int le,int ri,int pos,int v){
if (le==ri){
t[rt].m=t[rt].s=v;
return;
}
int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
if (pos<=mid)
change(ls,le,mid,pos,v);
else
change(rs,mid+1,ri,pos,v);
pushup(rt);
}
int query(int rt,int le,int ri,int xle,int xri,int ty){
if (le>xri||ri<xle)
return ty?0:-Inf;
if (xle<=le&&ri<=xri)
return ty?t[rt].s:t[rt].m;
int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
if (ty)
return query(ls,le,mid,xle,xri,ty)+query(rs,mid+1,ri,xle,xri,ty);
else
return max(query(ls,le,mid,xle,xri,ty),query(rs,mid+1,ri,xle,xri,ty));
}
int find(int a,int b,int t){
int f1=top[a],f2=top[b],ans=t?0:-Inf;
while (f1!=f2){
if (depth[f1]<depth[f2])
swap(f1,f2),swap(a,b);
if (t)
ans+=query(1,1,n,p[f1],p[a],t);
else
ans=max(ans,query(1,1,n,p[f1],p[a],t));
a=fa[f1],f1=top[a];
}
if (depth[a]>depth[b])
swap(a,b);
if (t)
ans+=query(1,1,n,p[a],p[b],t);
else
ans=max(ans,query(1,1,n,p[a],p[b],t));
return ans;
}
int main(){
scanf("%d",&n);
g.clear();
for (int i=1,a,b;i<n;i++){
scanf("%d%d",&a,&b);
g.add(a,b);
g.add(b,a);
}
for (int i=1;i<=n;i++)
scanf("%d",&v[i]);
cnp=0;
Get_Gen_Info(1,0,0);
Get_Pos(1,1);
build(1,1,n);
scanf("%d",&m);
for (int i=1;i<=m;i++){
char str[10];
int a,b,t;
scanf("%s%d%d",str,&a,&b);
if (str[0]=='C')
change(1,1,n,p[a],b);
else {
t=str[1]=='M'?0:1;
printf("%d\n",find(a,b,t));
}
}
return 0;
}

  

BZOJ1036 [ZJOI2008]树的统计Count 树链剖分的更多相关文章

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

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

  2. bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题

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

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

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

  4. Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT

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

  5. BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )

    树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...

  6. bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树

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

  7. BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)

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

  8. BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)(线段树单点修改)

    [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14968  Solved: 6079[Submit][Stat ...

  9. Cogs 1688. [ZJOI2008]树的统计Count(树链剖分+线段树||LCT)

    [ZJOI2008]树的统计Count ★★★ 输入文件:bzoj_1036.in 输出文件:bzoj_1036.out 简单对比 时间限制:5 s 内存限制:162 MB [题目描述] 一棵树上有n ...

随机推荐

  1. VMware虚拟机Mac OS X无法调整扩展硬盘大小的解决方案(转)

    使用VMware虚拟机搭建的MacOSX,在10.10以上可能会出现无法扩充磁盘大小的问题. 因为很多朋友在初次安装MacOSX的时候都默认选择40G的磁盘大小,结果用了没两天之后就发现磁盘不够用了. ...

  2. Tomcat数据源的原理,配置及使用(JNDI)

    Tomcat数据源的原理,配置及使用 知识点: 1.数据源的作用及操作原理; 2.Tomcat中数据源的配置; 3.数据源的查找及使用 传统JDBC使用过程存在以下四个步骤: 1.加载驱动程序 2.进 ...

  3. 20155117王震宇 2016-2017-2 《Java程序设计》第六周学习总结

    教材学习内容总结 IO流的分类: 根据流的数据对象来分: 高端流:所有的内存中的流都是高端流,比如:InputStreamReader 低端流:所有的外界设备中的流都是低端流,比如InputStrea ...

  4. android 获取图库中展示到界面中

    layout: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns: ...

  5. POJ1751 Highways【最小生成树】

    题意: 给你N个城市的坐标,城市之间存在公路,但是由于其中一些道路损坏了,需要维修,维修的费用与公路长成正比(公路是直的). 但现有M条公路是完整的,不需要维修,下面有M行,表示不需要维修的道路两端的 ...

  6. 下拉框combobox用法&级联餐单

    如果下来内容不用后台取数据,直接写死的话不用url属性,直接用data即可: <input id="orderstate" name="orderstate&quo ...

  7. SpringBoot2.x过滤器Filter和使用Servlet3.0配置自定义Filter实战

    补充:SpringBoot启动日志 1.深入SpringBoot2.x过滤器Filter和使用Servlet3.0配置自定义Filter实战(核心知识) 简介:讲解SpringBoot里面Filter ...

  8. 【逆向工具】IDA使用3-全局变量、数组、结构体

    全局变量 测试代码 全局变量既可以是某对象函数创建,也可以是在本程序任何地方创建.全局变量是可以被本程序所有对象或函数引用.下面这段代码中将int.float.char变量定义在main函数之外. / ...

  9. ActiveMQ 入门Nodejs版

    ActiveMQ 入门下载与安装 官方下载地址 解压,运行bin/win[32|64]/activemq[.bat] 启动服务 环境信息 控制台: http://localhost:8161 默认端口 ...

  10. expdp和impdp导入和导出数据

    一  关于expdp和impdp     使用EXPDP和IMPDP时应该注意的事项:EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用.EXPDP和IMPDP是服务端的工具程 ...