您的位置:首页 > 产品设计 > UI/UE

[SPOJ375]Query on a tree

2016-02-13 12:47 417 查看

传送门

http://cojs.tk/cogs/problem/problem.php?pid=1672

题目大意

支持

1.单边修改

2.查询两点间最大边权值

题解

就是上一道[POJ3237]树的维护的弱化版嘛

const
maxn=10010;
var
w:array[0..3*maxn,1..2]of longint;
x:array[0..maxn,1..3]of longint;
seg:array[0..8*maxn,1..5]of longint; {seg[3]:min; seg[4]:max}
side,val,pos,top,fa,son,size,dep:array[0..maxn]of longint;
i,j,k:longint;
n,m,len,a,b:longint;
cha,ch:char;
procedure swap(var a,b:longint);
var tt:longint;
begin tt:=a; a:=b; b:=tt; end;
function min(a,b:longint):longint;
begin if a>b then exit(b) else exit(a) end;
function max(a,b:longint):longint;
begin if a<b then exit(b) else exit(a) end;
procedure init(a,b:longint);
begin
w[len,1]:=b;
if w[a,2]=0 then w[a,2]:=len else w[w[a,1],2]:=len;
w[a,1]:=len; inc(len);
end;
procedure build(a,l,r:longint);
var mid:longint;
begin
seg[a,1]:=l; seg[a,2]:=r; seg[a,3]:=maxlongint; seg[a,4]:=-maxlongint; seg[a,5]:=0;
if l=r then exit;
mid:=(l+r)>>1;
build(a<<1,l,mid); build(a<<1+1,mid+1,r);
end;
procedure change(a,b,c:longint);
var mid:longint;
begin
if seg[a,1]=seg[a,2] then begin seg[a,3]:=c; seg[a,4]:=c; exit; end;
mid:=(seg[a,1]+seg[a,2])>>1;
if b<=mid then change(a<<1,b,c) else change(a<<1+1,b,c);
seg[a,3]:=min(seg[a<<1,3],seg[a<<1+1,3]); seg[a,4]:=max(seg[a<<1,4],seg[a<<1+1,4]);
end;
function query(a,l,r:longint):longint;
var mid:longint;
begin
if (seg[a,1]=l)and(seg[a,2]=r) then exit(seg[a,4]);
mid:=(seg[a,1]+seg[a,2])>>1;
if r<=mid then exit(query(a<<1,l,r)) else
if l>mid then exit(query(a<<1+1,l,r))
else exit(max(query(a<<1,l,mid),query(a<<1+1,mid+1,r)));
end;
procedure dfs1(a:longint); {fa,son,size,dep}
var tt,v:longint;
begin
tt:=w[a,2]; size[a]:=1; v:=0;
while tt<>0 do
begin
if w[tt,1]<>fa[a]
then
begin
20        fa[w[tt,1]]:=a; dep[w[tt,1]]:=dep[a]+1;
dfs1(w[tt,1]);
inc(size[a],size[w[tt,1]]); if size[w[tt,1]]>size[v] then v:=w[tt,1];
end;
tt:=w[tt,2];
end;
son[a]:=v;
end;
procedure dfs2(a,pre:longint); {top,pos}
var tt:longint;
begin
tt:=w[a,2]; top[a]:=pre; inc(len); pos[a]:=len; change(1,pos[a],val[a]);
if son[a]<>0 then dfs2(son[a],pre);
while tt<>0 do
begin
if (w[tt,1]<>fa[a])and(w[tt,1]<>son[a]) then dfs2(w[tt,1],w[tt,1]);
tt:=w[tt,2];
end;
end;
function queryans(a,b:longint):longint;
var ans,tt:longint;
begin
ans:=-maxlongint;
while top[a]<>top[b] do
begin
if dep[top[a]]<dep[top[b]] then swap(a,b);
tt:=query(1,pos[top[a]],pos[a]); ans:=max(ans,tt);
a:=fa[top[a]];
end;
if a=b then exit(ans);
if dep[a]<dep[b] then swap(a,b);
tt:=query(1,pos[b]+1,pos[a]); ans:=max(ans,tt);
exit(ans);
end;
begin
readln(n); len:=n+1;
for i:=1 to n-1 do
begin
readln(x[i,1],x[i,2],x[i,3]);
init(x[i,1],x[i,2]); init(x[i,2],x[i,1]);
end;
dep[1]:=1; fa[1]:=0; size[0]:=0;
dfs1(1);
for i:=1 to n-1 do
begin
if dep[x[i,1]]<dep[x[i,2]] then swap(x[i,1],x[i,2]);
val[x[i,1]]:=x[i,3]; side[i]:=x[i,1];
end;
len:=0; val[1]:=0;
build(1,1,n);
dfs2(1,1);
while not eof do
begin
read(cha); if cha='D' then break;
case cha of
'C':begin readln(ch,ch,ch,ch,ch,a,b); change(1,pos[side[a]],b); end;
'Q':begin readln(ch,ch,ch,ch,a,b); writeln(queryans(a,b)); end;
end;
end;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: