[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.
相关文章推荐
- Building Maintainable Software-java篇之Write Code Once
- MASQUERADE 和 SNAT的区别
- UI基础-01第一个iOS应用程序
- uva1121 - Subsequence
- Key-Value Observing
- Sidelinesoft NL5 Circuit Simulator 2.1.1
- poj2127Greatest Common Increasing Subsequence【LICS】
- zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)
- UITableView如何撤销移动操作
- UITableView如何撤销移动操作
- UITableView如何撤销移动操作
- Codeforces Round #342 (Div. 2) 625A Guest From the Past(贪心)
- 【SoapUI】在soapui中使用Groovy脚本常用方法
- 【SoapUI】自动化测试实施方法
- how to install cmake-gui on ubuntu
- 分治算法 Divide and Conquer Algorithm
- SpatialHadoop 中的 Operations 层 之 Range Query
- LeetCode Count Univalue Subtrees
- UIView的setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法之间的关系解释
- UIView的layoutSubviews和drawRect方法何时调用