树链剖分的基本题
详细介绍在http://blog.sina.com.cn/s/blog_7a1746820100wp67.html
通过树链剖分我们就可以在树上做线段树操作,完成解答

 const inf=;
type node=record
po,next:longint;
end;
point=record
max,sum:longint;
end; var tree:array[..] of point;
size,d,fa,p,b,c,top:array[..] of longint;
w:array[..] of node;
len,i,n,m,x,y,t:longint;
ch:char;
s:string; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; procedure update(i:longint);
begin
tree[i].sum:=tree[i*].sum+tree[i*+].sum;
tree[i].max:=max(tree[i*].max,tree[i*+].max);
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; procedure add(x,y:longint);
begin
inc(len);
w[len].po:=y;
w[len].next:=p[x];
p[x]:=len;
end; procedure dfs1(x:longint); //预处理
var i,y:longint;
begin
i:=p[x];
size[x]:=;
while i<> do
begin
y:=w[i].po;
if fa[x]<>y then
begin
fa[y]:=x;
d[y]:=d[x]+;
dfs1(y);
size[x]:=size[x]+size[y];
end;
i:=w[i].next;
end;
end; procedure dfs2(x:longint);
var i,y,q:longint;
begin
i:=p[x];
inc(t);
c[x]:=t;
q:=;
while i<> do
begin
y:=w[i].po;
if (c[y]=) and (size[q]<size[y]) then q:=y;
i:=w[i].next;
end;
if q<> then
begin
top[q]:=top[x]; //重儿子先访问
dfs2(q);
end;
i:=p[x]; //然后访问轻儿子
while i<> do
begin
y:=w[i].po;
if c[y]= then
begin
top[y]:=y;
dfs2(y);
end;
i:=w[i].next;
end;
end; procedure build(i,l,r:longint);
var m:longint;
begin
if l=r then
begin
tree[i].sum:=b[l];
tree[i].max:=b[l];
end
else begin
m:=(l+r) shr ;
build(i*,l,m);
build(i*+,m+,r);
update(i);
end;
end; procedure add(i,l,r:longint);
var m:longint;
begin
if l=r then
begin
tree[i].sum:=y;
tree[i].max:=y;
end
else begin
m:=(l+r) shr ;
if x<=m then add(i*,l,m) else add(i*+,m+,r);
update(i);
end;
end; function getmax(i,l,r,x,y:longint):longint;
var m,t:longint;
begin
if (x<=l) and (y>=r) then exit(tree[i].max)
else begin
m:=(l+r) shr ;
t:=-inf;
if x<=m then t:=max(t,getmax(i*,l,m,x,y));
if y>m then t:=max(t,getmax(i*+,m+,r,x,y));
exit(t);
end;
end; function getsum(i,l,r,x,y:longint):longint;
var m,t:longint;
begin
if (x<=l) and (y>=r) then exit(tree[i].sum)
else begin
m:=(l+r) shr ;
t:=;
if x<=m then t:=t+getsum(i*,l,m,x,y);
if y>m then t:=t+getsum(i*+,m+,r,x,y);
exit(t);
end;
end; function asksum(x,y:longint):longint;
var f1,f2:longint;
begin
asksum:=;
f1:=top[x];
f2:=top[y];
while f1<>f2 do
begin
if d[f1]>=d[f2] then
begin
asksum:=asksum+getsum(,,n,c[f1],c[x]);
x:=fa[f1];
end
else begin
asksum:=asksum+getsum(,,n,c[f2],c[y]);
y:=fa[f2];
end;
f1:=top[x];
f2:=top[y];
end;
if c[x]>c[y] then swap(x,y);
asksum:=asksum+getsum(,,n,c[x],c[y]);
end; function askmax(x,y:longint):longint;
var f1,f2,t:longint;
begin
t:=-inf;
f1:=top[x];
f2:=top[y];
while f1<>f2 do //提取
begin
if d[f1]>=d[f2] then
begin
t:=max(t,getmax(,,n,c[f1],c[x]));
x:=fa[f1];
end
else begin
t:=max(t,getmax(,,n,c[f2],c[y]));
y:=fa[f2];
end;
f1:=top[x];
f2:=top[y];
end;
if c[x]>c[y] then swap(x,y);
t:=max(t,getmax(,,n,c[x],c[y]));
exit(t);
end; begin
readln(n);
for i:= to n- do
begin
readln(x,y);
add(x,y);
add(y,x);
end;
d[]:=;
dfs1();
t:=;
top[]:=;
dfs2();
for i:= to n do
read(b[c[i]]);
build(,,n);
readln(m);
for i:= to m do
begin
read(ch);
s:='';
while ch<>' ' do
begin
s:=s+ch;
read(ch);
end;
readln(x,y);
if s='QMAX' then
writeln(askmax(x,y))
else if s='QSUM' then
writeln(asksum(x,y))
else if s='CHANGE' then
begin
x:=c[x];
b[x]:=y;
add(,,n);
end;
end;
end.

bzoj1036的更多相关文章

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

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

  2. 【bzoj1036】 ZJOI2008—树的统计Count

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036 (题目链接) 题意 动态维护树上两点间最大权值和权值和. Solution 裸树链剖分. 这一 ...

  3. 【BZOJ1036】 树的统计Count (树链剖分)

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

  4. BZOJ1036 [ZJOI2008]树的统计Count 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1036 题意概括 一个树,每个节点有一个权值.3种操作. 1:修改某一个节点的权值. 2:询问某两个 ...

  5. 【lct】bzoj1036 [ZJOI2008]树的统计Count

    题意:给你一棵树,点带权,支持三种操作:单点修改:询问链上和:询问链上max. 这里的Query操作用了与上一题不太一样的做法(上一题用那种做法,因为在边带权的情况下换根太困难啦): 先ChangeR ...

  6. [BZOJ1036][ZJOI2008]树的统计Count 解题报告|树链剖分

    树链剖分 简单来说就是数据结构在树上的应用.常用的为线段树splay等.(可现在splay还不会敲囧) 重链剖分: 将树上的边分成轻链和重链. 重边为每个节点到它子树最大的儿子的边,其余为轻边. 设( ...

  7. 洛谷3384&bzoj1036树链剖分

    值得注意的是: 一个点的子树是存在一起的...也就是说我们修改子树的时候只用... /********************************************************* ...

  8. 【BZOJ1036】树的统计Count(树链剖分,LCT)

    题意:一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: ...

  9. bzoj1036 [ZJOI2008]树的统计Count

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

  10. 【bzoj1036】[ZJOI2008]树的统计Count

    题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...

随机推荐

  1. Tomcat源码分析--转

    一.架构 下面谈谈我对Tomcat架构的理解 总体架构: 1.面向组件架构 2.基于JMX 3.事件侦听 1)面向组件架构 tomcat代码看似很庞大,但从结构上看却很清晰和简单,它主要由一堆组件组成 ...

  2. Java基础知识强化之集合框架笔记47:Set集合之TreeSet保证元素唯一性和比较器排序的原理及代码实现(比较器排序:Comparator)

    1. 比较器排序(定制排序) 前面我们说到的TreeSet的自然排序是根据集合元素的大小,TreeSet将它们以升序排列. 但是如果需要实现定制排序,比如实现降序排序,则要通过比较器排序(定制排序)实 ...

  3. HTTPS是如何保证连接安全:每位Web开发者都应知道的

    “HTTPS协议的工作原理是什么?”这是我在数天前工作项目中需要解决的问题. 作为一名Web开发者,我当然知道 HTTPS 协议是保障用户敏感数据的好办法,但并不知道这种协议的内在工作机制. 它怎么保 ...

  4. linux下sed命令笔记

    sed 流编辑器 Stream EDitor三大文本处理工具:grep,sed,awk 语法:sed 'AddressCommand' file ...Address:    1,StartLine, ...

  5. 巧用hidden传递参数

  6. apk文件解析,学习笔记

    Android 应用程序包文件 (APK) 是一种Android操作系统上的应用程序安装文件格式,其英文全称为 “application package file” . 如果懂得使用反编译工具,可以下 ...

  7. PrintWriter 和 BufferedWriter 写入文件.

    Ref: should I use PrintWriter to wrap BufferedWriter? The main reason for using PrintWriter is the w ...

  8. MSSQLSERVER未分离LDF删除情况下的MDF附加

    经过网上资料搜索,此方法可以解决. LDF日志不要轻易删除,恢复主数据要用到,如果删除,记得先分离,然后移动到另外的地方. 下面是针对未分离删除日志文件,MDF文件附加,提示找不到日志的问题的解决方法 ...

  9. 转-SecureCRT设置

    原帖地址:http://www.2cto.com/os/201410/341569.html 一.基本设置 1.修改设置 为了SecureCRT用起来更方便,需要做一些设置,需要修改的有如下几处: 1 ...

  10. OC - 27.CATransition

    概述 简介 CATransition又称转场动画,是CAAnimation的子类,可以直接使用 转场动画主要用于为图层提供移入/移出屏幕的动画效果 转场动画常见的应用是UINavigationCont ...