1036: [ZJOI2008]树的统计Count

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 7496  Solved: 3078
[Submit][Status][Discuss]

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

HINT

 

Source

树的分治

题解:phile神犇推荐的链剖模板题,一直不知道为啥挂掉,急死掉= =,最后发现居然把inline去掉就A了QAQ,逗我= =

事实证明——(引用phile神犇的原话)黑科技不可滥用TT

 type
point=^node;
node=record
g:longint;
next:point;
end;
var
i,j,k,l,m,n,tot,root:longint;a1:int64;
a:array[..] of point;ch:char;
d,e:array[..] of int64;
len,son,siz,top,list,f,num,anum:array[..] of longint;
c:array[..,..] of longint;
function min(x,y:longint):longint;
begin
if x<y then min:=x else min:=y;
end;
function max(x,y:longint):longint;
begin
if x>y then max:=x else max:=y;
end;
procedure swap(var x,y:longint);
var z:longint;
begin
z:=x;x:=y;y:=z;
end;
procedure add(x,y:longint);
var p:point;
begin
new(p);p^.g:=y;p^.next:=a[x];a[x]:=p;
end;
procedure dfs(y,x:longint);
var p:point;
begin
c[,x]:=y;siz[x]:=;len[x]:=len[y]+;son[x]:=;
p:=a[x];
while p<>nil do
begin
if p^.g<>y then
begin
dfs(x,p^.g);
inc(siz[x],siz[p^.g]);
if (son[x]=) or (siz[p^.g]>siz[son[x]]) then son[x]:=p^.g;
end;
p:=p^.next;
end;
end;
procedure dfs2(y,x,z:longint);
var p:point;
begin
top[x]:=z;inc(tot);num[x]:=tot;anum[tot]:=x;
if son[x]<> then dfs2(x,son[x],z);p:=a[x];
while p<>nil do
begin
if (p^.g<>y) and (p^.g<>son[x]) then dfs2(x,p^.g,p^.g);
p:=p^.next;
end;
end;
procedure built(z,x,y:longint);
begin
if x=y then
begin
list[x]:=z;
d[z]:=f[anum[x]];
e[z]:=d[z];
end
else
begin
built(z*,x ,(x+y) div );
built(z*+,(x+y) div +,y);
d[z]:=d[z*]+d[z*+];
if e[z*+]>e[z*] then e[z]:=e[z*+] else e[z]:=e[z*];
end;
end;
procedure change(x:longint;y:int64);
begin
x:=list[x];d[x]:=y;e[x]:=y;x:=x div ;
while x> do
begin
d[x]:=d[x*]+d[x*+];
if e[x*+]>e[x*] then e[x]:=e[x*+] else e[x]:=e[x*];
x:=x div ;
end;
end;
function sum(z,x,y,l,r:longint):int64;
begin
if l>r then exit();
if (x=l) and (y=r) then exit(d[z]);
exit(sum(z*,x,(x+y) div ,l,min(r,(x+y) div ))+sum(z*+,(x+y) div +,y,max((x+y) div +,l),r));
end;
function getmax(z,x,y,l,r:longint):int64;
var a1,a2:int64;
begin
if l>r then exit(-maxlongint*maxlongint);
if (x=l) and (y=r) then exit(e[z]);
a1:=getmax(z*,x,(x+y) div ,l,min(r,(x+y) div ));
a2:=getmax(z*+,(x+y) div +,y,max((x+y) div +,l),r);
if a1>a2 then exit(a1) else exit(a2);
end;
function getup(x,y:longint):longint;
var i:longint;
begin
i:=;
while y> do
begin
if odd(y) then x:=c[i,x];
inc(i);y:=y div ;
end;
exit(x);
end;
function getcom(x,y:longint):longint;
var i:longint;
begin
if len[x]<len[y] then swap(x,y);
x:=getup(x,len[x]-len[y]);
if x=y then exit(x);
for i:=trunc(round(ln(len[x])/ln())) downto do
if c[i,x]<>c[i,y] then
begin
x:=c[i,x];
y:=c[i,y];
end;
exit(c[,x]);
end;
procedure treechange(x:longint;y:int64);
begin
change(num[x],y);
end;
function treesum(x,y:longint):int64;
var i,z:longint;
begin
z:=getcom(x,y);treesum:=;
repeat
if len[top[x]]<len[z] then i:=z else i:=top[x];
inc(treesum,sum(,,n,num[i],num[x]));
if i=z then break;
x:=c[,i];
until false;
repeat
if len[top[y]]<len[z] then i:=z else i:=top[y];
inc(treesum,sum(,,n,num[i],num[y]));
if i=z then break;
y:=c[,i];
until false;
dec(treesum,sum(,,n,num[z],num[z]));
end;
function treemax(x,y:longint):int64;
var i,z:longint;a1:int64;
begin
treemax:=-maxlongint*maxlongint;
z:=getcom(x,y);
repeat
if len[top[x]]<len[z] then i:=z else i:=top[x];
a1:=getmax(,,n,num[i],num[x]);
if a1>treemax then treemax:=a1;
if i=z then break;
x:=c[,i];
until false;
repeat
if len[top[y]]<len[z] then i:=z else i:=top[y];
a1:=getmax(,,n,num[i],num[y]);
if a1>treemax then treemax:=a1;
if i=z then break;
y:=c[,i];
until false;
end;
begin
readln(n);
for i:= to n do a[i]:=nil;
for i:= to n- do
begin
readln(j,k);
add(j,k);add(k,j);
end;
for i:= to n do read(f[i]);readln;
root:=random(n)+;dfs(,root);dfs2(,root,root);
for i:= to trunc(round(ln(n)/ln()))+ do
for j:= to n do
c[i,j]:=c[i-,c[i-,j]];
built(,,n);
readln(m);
for i:= to m do
begin
read(ch,ch);
case upcase(ch) of
'M':begin
readln(ch,ch,j,k);
writeln(treemax(j,k));
end;
'S':begin
readln(ch,ch,j,k);
writeln(treesum(j,k));
end;
'H':begin
readln(ch,ch,ch,ch,j,a1);
treechange(j,a1);
end;
end;
end;
readln;
end.

1036: [ZJOI2008]树的统计Count的更多相关文章

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

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

  2. BZOJ 1036: [ZJOI2008]树的统计Count

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

  3. bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

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

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

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

  5. 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count

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

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

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

  7. Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树)

    Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树) Description 一棵树上有n个节点,编号分别 ...

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

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

  9. bzoj 1036: [ZJOI2008]树的统计Count (树链剖分+线段树 点权)

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

随机推荐

  1. C# 定时器计划任务

    函数类: public class MyPlan { public void RunMyplan(object source, ElapsedEventArgs e) { //读取配置文件设定的日期时 ...

  2. 关于Vue.js 使用v-cloak后仍显示变量的解决方法

    v-cloak   这个指令是防止页面加载时出现 vuejs 的变量名而设计的,但有时候添加了这个指令仍会显示变量,这是怎么回事呢?. v-cloak 用法: HTML代码: <div v-cl ...

  3. Bootstrap入门(十二)组件6:导航标签页

    Bootstrap入门(十二)组件6:导航标签页   1.标签页 2.胶囊式标签页 3.垂直展示 4.两端对齐的标签页 5.禁用的链接 6.添加下拉菜单   先引入本地的CSS文件和JS文件(注:1. ...

  4. Redis系列二(yum切换为网易163)

    这个可能和Redis没有直接的关系... 是我在yum install的时候发现centos的yum实在是太慢,上网查了下.网易163有个yum镜像,为了让CentOS6使用速度更快的YUM更新源,可 ...

  5. CMD修改IP地址

    在操作系统下,我们可以使用"本地连接"的属性来修改IP地址,但是如果我们要在多个IP地址之间切换,使用这种方法未免过于麻烦.我们可以使用NETSH命令来添加,相当简便.使用DOS修 ...

  6. JS如何实现点击页面其他地方隐藏菜单?

    方法一: $("#a").on("click", function(e){  $("#menu").show();    $(documen ...

  7. 基于basys2用verilog设计多功能数字钟(重写)

    话不多说先上图         前言 自从学习FPGA以来,唯一做过的完整系统就是基于basys2得多功能数字表.记得当时做的时候也没少头疼,最后用时间磨出来了一个不是很完整的小系统,当时还是产生了满 ...

  8. C++ 构造函数和析构函数的调用顺序、虚析构函数的作用

    构造函数和析构函数的调用顺序 构造函数的调用顺序: 当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的构造函数,依次类推,直至到达最底层的目标派生类的构造函数为止. 析构函数的调用书序: ...

  9. .Net下的分库分表帮助类——用分库的思想来分表

    简介     在大型项目中,我们会遇到分表分库的情景.      分库,将不同模块对应的表拆分到对应的数据库下,其实伴随着公司内分布式系统的出现,这个过程也是自然而然就发生了,对应商品模块和用户模块, ...

  10. Android Studio --“Cannot resolve symbol” 解决办法

    鼠标放上去后显示 “Cannot resolve symbol XXX”,重启 Android Studio,重新 sync gradle,Clean build 都没有用. 多半是因为 Androi ...