Description

  一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

Input

  输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 
     对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

Output

  对于每个“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
 
 
没什么可说的,就是复习一下树链剖分模板。
以前做过,那是还是用指针存树的,也是dfs的。
现在写的是数组模拟邻接表,以及非递归的预处理。
这个非递归预处理可以使子树和链都在一起,也可以只保证链在一起,这题没有子树操作,只要后者即可,但也写了下使子树在一起的代码。
先是只保证链在一起的代码:
 program rrr(input,output);
const
inf=;
type
treetype=record
l,r,max,sum:longint;
end;
etype=record
t,next:longint;
end;
var
a:array[..]of treetype;
b,c,father,siz,son,ss,idx,head,q,dep:array[..]of longint;
e:array[..]of etype;
n,m,i,j,x,y,cnt,h,t,ans:longint;
s:string;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
procedure add(x,y:longint);
begin
inc(cnt);e[cnt].t:=y;e[cnt].next:=c[x];c[x]:=cnt;
end;
procedure work;
begin
j:=pos(' ',s);val(copy(s,,j-),x);delete(s,,j);val(s,y);
end;
procedure prepare;
begin
h:=;t:=;q[]:=;father[]:=;dep[]:=;
while h<t do
begin
inc(h);
i:=c[q[h]];
while i<> do
begin
if e[i].t<>father[q[h]] then
begin
father[e[i].t]:=q[h];dep[e[i].t]:=dep[q[h]]+;
inc(t);q[t]:=e[i].t;
end;
i:=e[i].next;
end;
end;
fillchar(son,sizeof(son),);fillchar(ss,sizeof(ss),);
for i:= to n do siz[i]:=;
for i:=n downto do
begin
inc(siz[father[q[i]]],siz[q[i]]);
if siz[q[i]]>ss[father[q[i]]] then
begin ss[father[q[i]]]:=siz[q[i]];son[father[q[i]]]:=q[i]; end;
end;
cnt:=;fillchar(idx,sizeof(idx),);
for i:= to n do
if idx[q[i]]= then
begin
j:=q[i];
while j<> do begin inc(cnt);idx[j]:=cnt;head[j]:=q[i];j:=son[j]; end;
end;
end;
procedure build(k,l,r:longint);
var
mid,i:longint;
begin
a[k].l:=l;a[k].r:=r;
if l=r then begin a[k].max:=b[l];a[k].sum:=b[l];exit; end;
mid:=(l+r)>>;i:=k+k;
build(i,l,mid);
build(i+,mid+,r);
a[k].max:=max(a[i].max,a[i+].max);
a[k].sum:=a[i].sum+a[i+].sum;
end;
procedure change(k,x,y:longint);
var
mid,i:longint;
begin
if a[k].l=a[k].r then begin a[k].sum:=y;a[k].max:=y;exit end;
mid:=(a[k].l+a[k].r)>>;i:=k+k;
if x<=mid then change(i,x,y) else change(i+,x,y);
a[k].max:=max(a[i].max,a[i+].max);
a[k].sum:=a[i].sum+a[i+].sum;
end;
function askmax(k,x,y:longint):longint;
var
mid,ans:longint;
begin
if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].max);
mid:=(a[k].l+a[k].r)>>;
ans:=-inf;
if x<=mid then ans:=askmax(k+k,x,y);
if mid<y then ans:=max(ans,askmax(k+k+,x,y));
exit(ans);
end;
function asksum(k,x,y:longint):longint;
var
mid,ans:longint;
begin
if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].sum);
mid:=(a[k].l+a[k].r)>>;
ans:=;
if x<=mid then ans:=asksum(k+k,x,y);
if mid<y then ans:=ans+asksum(k+k+,x,y);
exit(ans);
end;
procedure qmax;
begin
ans:=-inf;
while head[x]<>head[y] do
if dep[head[x]]>dep[head[y]] then
begin
ans:=max(ans,askmax(,idx[head[x]],idx[x]));
x:=father[head[x]];
end
else begin
ans:=max(ans,askmax(,idx[head[y]],idx[y]));
y:=father[head[y]];
end;
if dep[x]>dep[y] then ans:=max(ans,askmax(,idx[y],idx[x]))
else ans:=max(ans,askmax(,idx[x],idx[y]));
end;
procedure qsum;
begin
ans:=;
while head[x]<>head[y] do
if dep[head[x]]>dep[head[y]] then
begin
ans:=ans+asksum(,idx[head[x]],idx[x]);
x:=father[head[x]];
end
else begin
ans:=ans+asksum(,idx[head[y]],idx[y]);
y:=father[head[y]];
end;
if dep[x]>dep[y] then ans:=ans+asksum(,idx[y],idx[x])
else ans:=ans+asksum(,idx[x],idx[y]);
end;
begin
assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
readln(n);
fillchar(c,sizeof(c),);cnt:=;
for i:= to n- do begin readln(x,y);add(x,y);add(y,x); end;
prepare;
for i:= to n do read(b[idx[i]]);
build(,,n);
readln(m);
for i:= to m do
begin
readln(s);
if s[]='C' then begin delete(s,,);work;change(,idx[x],y); end
else if s[]='M' then begin delete(s,,);work;qmax;writeln(ans); end
else begin delete(s,,);work;qsum;writeln(ans); end;
end;
close(input);close(output);
end.

然后是是子树也在一起的代码:

 program rrr(input,output);
const
inf=;
type
treetype=record
l,r,max,sum:longint;
end;
etype=record
t,next:longint;
end;
var
a:array[..]of treetype;
b,c,father,siz,son,ss,idx,head,q,dep,ot:array[..]of longint;
e:array[..]of etype;
n,m,i,j,x,y,cnt,h,t,ans:longint;
s:string;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
procedure add(x,y:longint);
begin
inc(cnt);e[cnt].t:=y;e[cnt].next:=c[x];c[x]:=cnt;
end;
procedure work;
begin
j:=pos(' ',s);val(copy(s,,j-),x);delete(s,,j);val(s,y);
end;
procedure prepare;
begin
h:=;t:=;q[]:=;father[]:=;dep[]:=;
while h<t do
begin
inc(h);
i:=c[q[h]];
while i<> do
begin
if e[i].t<>father[q[h]] then
begin
father[e[i].t]:=q[h];dep[e[i].t]:=dep[q[h]]+;
inc(t);q[t]:=e[i].t;
end;
i:=e[i].next;
end;
end;
fillchar(son,sizeof(son),);fillchar(ss,sizeof(ss),);
for i:= to n do siz[i]:=;
for i:=n downto do
begin
inc(siz[father[q[i]]],siz[q[i]]);
if siz[q[i]]>ss[father[q[i]]] then
begin ss[father[q[i]]]:=siz[q[i]];son[father[q[i]]]:=q[i]; end;
end;
fillchar(idx,sizeof(idx),);ot[]:=;
for i:= to n do
if idx[q[i]]= then
begin
cnt:=ot[father[q[i]]];j:=q[i];
while j<> do
begin
head[j]:=q[i];
inc(cnt);idx[j]:=cnt;
ot[j]:=cnt;inc(ot[father[j]],siz[j]);
j:=son[j];
end;
end;
end;
procedure build(k,l,r:longint);
var
mid,i:longint;
begin
a[k].l:=l;a[k].r:=r;
if l=r then begin a[k].max:=b[l];a[k].sum:=b[l];exit; end;
mid:=(l+r)>>;i:=k+k;
build(i,l,mid);
build(i+,mid+,r);
a[k].max:=max(a[i].max,a[i+].max);
a[k].sum:=a[i].sum+a[i+].sum;
end;
procedure change(k,x,y:longint);
var
mid,i:longint;
begin
if a[k].l=a[k].r then begin a[k].sum:=y;a[k].max:=y;exit end;
mid:=(a[k].l+a[k].r)>>;i:=k+k;
if x<=mid then change(i,x,y) else change(i+,x,y);
a[k].max:=max(a[i].max,a[i+].max);
a[k].sum:=a[i].sum+a[i+].sum;
end;
function askmax(k,x,y:longint):longint;
var
mid,ans:longint;
begin
if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].max);
mid:=(a[k].l+a[k].r)>>;
ans:=-inf;
if x<=mid then ans:=askmax(k+k,x,y);
if mid<y then ans:=max(ans,askmax(k+k+,x,y));
exit(ans);
end;
function asksum(k,x,y:longint):longint;
var
mid,ans:longint;
begin
if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].sum);
mid:=(a[k].l+a[k].r)>>;
ans:=;
if x<=mid then ans:=asksum(k+k,x,y);
if mid<y then ans:=ans+asksum(k+k+,x,y);
exit(ans);
end;
procedure qmax;
begin
ans:=-inf;
while head[x]<>head[y] do
if dep[head[x]]>dep[head[y]] then
begin
ans:=max(ans,askmax(,idx[head[x]],idx[x]));
x:=father[head[x]];
end
else begin
ans:=max(ans,askmax(,idx[head[y]],idx[y]));
y:=father[head[y]];
end;
if dep[x]>dep[y] then ans:=max(ans,askmax(,idx[y],idx[x]))
else ans:=max(ans,askmax(,idx[x],idx[y]));
end;
procedure qsum;
begin
ans:=;
while head[x]<>head[y] do
if dep[head[x]]>dep[head[y]] then
begin
ans:=ans+asksum(,idx[head[x]],idx[x]);
x:=father[head[x]];
end
else begin
ans:=ans+asksum(,idx[head[y]],idx[y]);
y:=father[head[y]];
end;
if dep[x]>dep[y] then ans:=ans+asksum(,idx[y],idx[x])
else ans:=ans+asksum(,idx[x],idx[y]);
end;
begin
assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
readln(n);
fillchar(c,sizeof(c),);cnt:=;
for i:= to n- do begin readln(x,y);add(x,y);add(y,x); end;
prepare;
for i:= to n do read(b[idx[i]]);
build(,,n);
readln(m);
for i:= to m do
begin
readln(s);
if s[]='C' then begin delete(s,,);work;change(,idx[x],y); end
else if s[]='M' then begin delete(s,,);work;qmax;writeln(ans); end
else begin delete(s,,);work;qsum;writeln(ans); end;
end;
close(input);close(output);
end.

其实大部分都是一模一样的,只是预处理不一样。

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 ...

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

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

随机推荐

  1. 【JUC源码解析】Phaser

    简介 Phaser,阶段器,可作为一个可复用的同步屏障,与CyclicBarrier和CountDownLatch类似,但更强大. 全览图 如上图所示,phaser,支持phaser树(图中,简化为p ...

  2. $.ready和onload 区别

    1.jq ready()的方法就是Dom Ready 他的作用或者意义就是:在DOM加载完成后就可以可以对DOM进行操作. 一般情况先一个页面响应加载的顺序是,域名解析-加载html-加载js和css ...

  3. SpringBoot日记——Thymeleaf模板引擎篇

    开发通常我们都会使用模板引擎,比如:JSP.Velocity.Freemarker.Thymeleaf等等很多,那么模板引擎是干嘛用的? 模板引擎,顾名思义,是一款模板,模板中可以动态的写入一些参数, ...

  4. fiddler和bugfree之间的联动(做伪请求、伪响应、并发、抓密码)

    青.取之于蓝,而青于蓝:冰.水为之,而寒于水 不积跬步,无以至千里;不积小流,无以成江海. 1解压Fiddler Web Debugger V4.6.2017修正中文第6版至C盘Program Fil ...

  5. could not launch process: decoding dwarf section info at offset 0x0: too short

    Fabric调试异常 作者在使用chaincode进行智能合约开发的过程中,使用Goland + Golang + win10_X64作为开发环境: GoLand 2018.1.4 Build #GO ...

  6. 为什么HashMap桶(链表)的长度超过8会转换成红黑树?

    百度了一下,感觉能说清楚的并不多,所以在此记录一下. 首先说一说转换为红黑树的必要性: 红黑树的插入.删除和遍历的最坏时间复杂度都是log(n), 因此,意外的情况或者恶意使用下导致hashCode( ...

  7. 【视频编解码·学习笔记】12. 图像参数集(PPS)介绍

    一.PPS相关概念: 除了序列参数集SPS之外,H.264中另一重要的参数集合为图像参数集Picture Paramater Set(PPS). 通常情况下,PPS类似于SPS,在H.264的裸码流中 ...

  8. [T-ARA/超新星][TTL (Time To Love)]

    歌词来源:http://music.163.com/#/song?id=5403002 作曲 : 金道勋 [作曲 : 金道勋] 作词 : Rhymer/Joosuc/황성진 [作词 : Rhymer/ ...

  9. 王者荣耀交流协会final发布-第一次scrum立会

    1.例会照片 成员王超,高远博,冉华,王磊,王玉玲,任思佳,袁玥全部到齐 master:袁玥 2.时间跨度 2017年12月1日 17:00 — 17:31,总计31分钟 3.地点 一食堂二楼沙发座椅 ...

  10. Git基础级介绍

    这篇随笔是在学习了廖雪峰老师的git教程之后写的总结,要看详细的基础级git介绍可以去http://www.liaoxuefeng.com/wiki/0013739516305929606dd1836 ...