BZOJ 1036: [ZJOI2008]树的统计Count(树链剖分)
树的统计Count
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
4
1
2
2
10
6
5
6
5
16
分析:
树链剖分模板题,参照hzwer的程序写的。
代码:
program bzoj_;
type
point=record
l,r,sum,max:longint;
end;
message=record
t,next:longint;
end;
var
e:array[..]of message;
w:array[..]of point;
fa:array[..,..]of longint;
head,v,size,belong,deep,post:array[..]of longint;
vis:array[..]of boolean;
n,m,sz:longint;
procedure insert(x,y:longint);
begin
inc(m); e[m].t:=x; e[m].next:=head[y]; head[y]:=m;
inc(m); e[m].t:=y; e[m].next:=head[x]; head[x]:=m;
end;
function max(x,y:longint):longint;
begin
if x>y then max:=x else max:=y;
end;
procedure int;
var i,x,y:longint;
begin
readln(n); sz:=; m:=;
for i:= to n- do
begin readln(x,y); insert(x,y); end;
for i:= to n do read(v[i]);
fillchar(vis,sizeof(vis),false);
end;
procedure dfs1(x:longint);
var i:longint;
begin
size[x]:=; vis[x]:=true;
for i:= to do
begin
if deep[x]<(<<i) then break;
fa[x,i]:=fa[fa[x,i-],i-];
end;
i:=head[x];
while i> do
begin
if vis[e[i].t] then begin i:=e[i].next; continue; end;
deep[e[i].t]:=deep[x]+;
fa[e[i].t][]:=x;
dfs1(e[i].t);
inc(size[x],size[e[i].t]);
i:=e[i].next;
end;
end;
procedure dfs2(x,chain:longint);
var i,k:longint;
begin
k:=; inc(sz);post[x]:=sz;belong[x]:=chain;
i:=head[x];
while i> do
begin
if (deep[e[i].t]>deep[x])and(size[e[i].t]>size[k]) then k:=e[i].t;
i:=e[i].next;
end;
if k= then exit;
dfs2(k,chain);
i:=head[x];
while i> do
begin
if (deep[e[i].t]>deep[x])and(k<>e[i].t) then dfs2(e[i].t,e[i].t);
i:=e[i].next;
end;
end;
function lca(x,y:longint):longint;
var i,t,u:longint;
begin
if deep[x]<deep[y] then begin u:=x; x:=y; y:=u; end;
t:=deep[x]-deep[y];
for i:= to do
if (t and (<<i))> then x:=fa[x,i];
for i:= downto do
if (fa[x,i]<>fa[y,i]) then begin x:=fa[x,i];y:=fa[y,i]; end;
if x=y then exit(x) else exit(fa[x,]);
end;
procedure build(p,l,r:longint);
var mid:longint;
begin
w[p].l:=l; w[p].r:=r; w[p].max:=-maxlongint; w[p].sum:=;
if l=r then exit; mid:=(l+r) div ;
build(p*,l,mid); build(p*+,mid+,r);
end;
procedure change(p,x,num:longint);
var mid:longint;
begin
if w[p].l=w[p].r then begin w[p].sum:=num; w[p].max:=num; end
else
begin
mid:=(w[p].l+w[p].r) div ;
if x<=mid then change(p*,x,num) else
if x>mid then change(p*+,x,num);
w[p].sum:=w[p*].sum+w[p*+].sum;
w[p].max:=max(w[p*].max,w[p*+].max);
end;
end;
function querysum(p,l,r:longint):longint;
var mid,ans:longint;
begin
if (l<=w[p].l)and(w[p].r<=r) then exit(w[p].sum)
else
begin
mid:=(w[p].l+w[p].r) div ; ans:=;
if l<=mid then inc(ans,querysum(p*,l,r));
if r>mid then inc(ans,querysum(p*+,l,r));
exit(ans);
end;
end;
function querymax(p,l,r:longint):longint;
var mid,ans:longint;
begin
if (l<=w[p].l)and(w[p].r<=r) then exit(w[p].max)
else
begin
mid:=(w[p].l+w[p].r) div ; ans:=-maxlongint;
if l<=mid then ans:=max(ans,querymax(p*,l,r));
if r>mid then ans:=max(ans,querymax(p*+,l,r));
exit(ans);
end;
end;
function solvesum(x,f:longint):longint;
var sum:longint;
begin
sum:=;
while (belong[x]<>belong[f]) do
begin
inc(sum,querysum(,post[belong[x]],post[x])); x:=fa[belong[x],];
end;
inc(sum,querysum(,post[f],post[x])); exit(sum);
end;
function solvemax(x,f:longint):longint;
var ans:longint;
begin
ans:=-maxlongint;
while (belong[x]<>belong[f]) do
begin
ans:=max(ans,querymax(,post[belong[x]],post[x]));x:=fa[belong[x],];
end;
ans:=max(ans,querymax(,post[f],post[x])); exit(ans);
end;
procedure solve;
var i,x,y,q,t,l:longint; s:string; ch,gy:char;
begin
build(,,n);
for i:= to n do
change(,post[i],v[i]);
readln(q);
for i:= to q do
begin
readln(s); ch:=s[]; gy:=s[];
l:=pos(' ',s); delete(s,,l);
l:=pos(' ',s); val(copy(s,,l-),x);
val(copy(s,l+,length(s)-l),y);
if ch='C' then begin v[x]:=y; change(,post[x],y); end
else
begin
t:=lca(x,y); if gy='M' then writeln(max(solvemax(x,t),solvemax(y,t)))
else writeln(solvesum(x,t)+solvesum(y,t)-v[t]);
end;
end;
end;
begin
assign(input,'bzoj_1036.in');reset(input);
assign(output,'bzoj_1036.out');rewrite(output);
int;
dfs1(); dfs2(,); solve;
close(input); close(output);
end.
BZOJ 1036: [ZJOI2008]树的统计Count(树链剖分)的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 11102 Solved: 4490[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...
- bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 16294 Solved: 6645[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14982 Solved: 6081[Submit ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)(线段树单点修改)
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14968 Solved: 6079[Submit][Stat ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
- bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题
[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...
- Cogs 1688. [ZJOI2008]树的统计Count(树链剖分+线段树||LCT)
[ZJOI2008]树的统计Count ★★★ 输入文件:bzoj_1036.in 输出文件:bzoj_1036.out 简单对比 时间限制:5 s 内存限制:162 MB [题目描述] 一棵树上有n ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
随机推荐
- 进程加载与segment
elf文件是一组结构体和数据的组合. elf文件是一种文件格式,这种格式定义了进程加载器如何读取elf文件的内容. elf文件的程序头或者segment对如何加载(读取)做了说明.
- 2018.6.22 Java试题测试结果
如何从有数字规律的网址抓取网页并保存在当前目录?假设网址为 http://test/0.xml,其中这个数字可以递增到100. for((i=0;i<100;++i));do wget http ...
- 2018.5.24 Oracle下的sqlplus编程 块结构
1.语句结构模板 declare --声明 begin dbms_output.put_line('Legend Hello world'); end; 2.变量使用 & 是输入符号 decl ...
- Flutter 入坑(1):flutter 环境搭建,window版本
下载安装JAVA环境 1. 既然要做原生应用了,而且是基于Android的,那还是需要我们安装一下JAVA的环境的,我比一般得到一个新系统后首先做的就是这一步. https://www.orac ...
- 2018.11.7 Nescafe29 T1 穿越七色虹
题目 题目背景 在 Nescafe27 和 28 中,讲述了一支探险队前往 Nescafe 之塔探险的故事…… 当两位探险队员以最快的时间把礼物放到每个木箱里之后,精灵们变身为一缕缕金带似的光,簇簇光 ...
- c++运算符重载和虚函数
运算符重载与虚函数 单目运算符 接下来都以AClass作为一个类例子介绍 AClass{ int var } 区分后置++与前置++ AClass operator ++ () ++前置 一般设计为返 ...
- ES6 的解构赋值前每次都创建一个对象吗?会加重 GC 的负担吗?
本文来源于知乎上的一个提问. 为了程序的易读性,我们会使用 ES6 的解构赋值: function f({a,b}){} f({a:1,b:2}); 这个例子的函数调用中,会真的产生一个对象吗?如果会 ...
- JZOJ 5812. 【NOIP提高A组模拟2018.8.14】 区间
5812. [NOIP提高A组模拟2018.8.14] 区间 (File IO): input:range.in output:range.out Time Limits: 1000 ms Memo ...
- keil swd设置下载stm32f103c8t6.
1.debug选项,选择jlink,2.utilities选择jlink3.加载flash算法.4.选择swd模式,其他基本上默认,这样就可以下载了对rom和ram设置需要说明一下:1,IROM1,前 ...
- [BZOJ3625][CF438E]小朋友和二叉树
题面 Description 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树. 考虑一个含有\(n\)个互异正整数的序列\(c_1,c_2,\ldots,c_n\).如果一棵带点权的有根二叉树满足其 ...