树链剖分的基本题
详细介绍在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. Android Studio快速生成get set等函数

    方式一:Code-->Generate 方式二:通过快捷键Alt+Insert

  2. CUDA与VS2013安装

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  3. 用Java发送邮件

    要用Java发送邮件,除过JDK本身的jar包之外,还需要两个额外的jar包:JavaMail和JAF.当然,如果你使用的JavaEE的JDK,那就不用单独去网上下载了,因为JavaEE的JDK中已经 ...

  4. 版本控制-cvs

    我们实训用的是cvs. 团队协作: 代码版本控制软件:CVS.SVN.GIT(Git@开源中国) FTP:服务端.客户端 CVS: 服务端(源码仓库).客户端

  5. 如何在安卓/data(而不是/data/data)目录下进行文件的读写操作

    分析:Android默认是无法直接操作/data目录的,只能读写程序自己的私有目录,也就是/data/data/package name/下,默认只能操作这个目录下的文件,也就是我们想直接读写/dat ...

  6. ASP.NET 导入EXCEL文档

    鉴于教务一般都是手动输入学生信息,在未了解本校数据库的客观情况之下,我们准备设计一个导入excel文档中学生信息如数据库的功能.结合网上各类大牛的综合版本出炉.. 首先具体的实现思想如下: 1.先使用 ...

  7. style currentStyle getComputedStyle的区别和用法

    先介绍下层叠样式表的三种形式: 1.内联样式,在html标签中style属性设置. <p style="color:#f90">内联样式</p> 2.嵌入样 ...

  8. 用连接池提高Servlet访问数据库的效率

    Java Servlet作为首选的服务器端数据处理技术,正在迅速取代CGI脚本.Servlet超越CGI的优势之一在于,不仅多个请求可以共享公用资源,而且还可以在不同用户请求之间保留持续数据.本文介绍 ...

  9. iOS 视频播放横屏,隐藏状态栏

    MPMoviePlayerViewController *moviePlayerViewController = [[MPMoviePlayerViewController alloc] init]; ...

  10. [翻译]jQuery十周年-John Resig

    10th Anniversary of jQuery Today marks the 10th anniversary of the release of jQuery...[原文] 今天是jQuer ...