題目大意:
給你一顆樹,要求支援下列3個操作:
1.詢問兩點之間路徑的邊中邊權最大的;
2.把兩點之間的路徑的邊權全部取反;
3.修改某條邊的邊權。
最近想強化下動態樹(路徑剖分就算了,又慢又醜),spoj上有4道qtree,只可惜家裡上spoj太慢。。
ms pku3237這道題比qtree的操作還多一點。
編了2個小時,花了半個小時調過了範例,交上去TLE了,估計是死迴圈,寫了個資料產生器,發現是數組沒清0;
之後又WA了一次,有個特殊情況沒判到,就是點A是點B的祖先,之後就A了。。。
隨機產生的資料連暴力都比這個動態樹快。。不過這道題資料稍微水了點,資料範圍也不大。
速度比較慢,表噴。。。
program poj3237; const mn=10000;<br />var<br /> d,next,p,c,e,l,r,w,fa,max,min:array[0..2*mn] of longint;<br /> root,o,ff:array[0..mn] of boolean; q:char;<br /> i,j,k,a,b,t,n,g,cc,ll,rr,ans,task:longint;</p><p>procedure update(i:longint);<br />begin<br /> ll:=l[i];rr:=r[i];<br /> min[i]:=w[i];max[i]:=w[i];<br /> if min[ll]<min[i] then min[i]:=min[ll];<br /> if min[rr]<min[i] then min[i]:=min[rr];<br /> if max[ll]>max[i] then max[i]:=max[ll];<br /> if max[rr]>max[i] then max[i]:=max[rr];<br />end;</p><p>procedure left(var i:longint);<br />begin<br /> j:=r[i];r[i]:=l[j];fa[r[i]]:=i;l[j]:=i;<br /> update(i);update(j);<br /> root[j]:=root[i];root[i]:=false;<br /> fa[j]:=fa[i];fa[i]:=j;i:=j;<br />end;</p><p>procedure right(var i:longint);<br />begin<br /> j:=l[i];l[i]:=r[j];fa[l[i]]:=i;r[j]:=i;<br /> update(i);update(j);<br /> root[j]:=root[i];root[i]:=false;<br /> fa[j]:=fa[i];fa[i]:=j;i:=j;<br />end;</p><p>procedure fan(i:longint);<br />begin<br /> if i=0 then exit;<br /> ff[i]:=not ff[i];w[i]:=-w[i];<br /> j:=-max[i];max[i]:=-min[i];min[i]:=j;<br />end;</p><p>procedure splay(var i:longint);<br />begin<br /> if ff[i] then begin<br /> fan(l[i]);fan(r[i]);ff[i]:=false;<br /> end;<br /> o[i]:=false;<br /> if o[l[i]] then begin<br /> splay(l[i]);right(i);<br /> end else<br /> if o[r[i]] then begin<br /> splay(r[i]);left(i);<br /> end;<br />end;</p><p>procedure cut(i,z:longint);<br />begin<br /> while not root[i] do begin<br /> o[i]:=true;i:=fa[i];<br /> end;<br /> splay(i);g:=l[i];<br /> if z=0 then exit;<br /> root[g]:=true;<br /> l[i]:=0;update(i);<br />end;</p><p>procedure access(i:longint);<br />begin<br /> cut(i,1);t:=i;<br /> while fa[i]<>0 do begin<br /> cut(fa[i],1);l[fa[i]]:=i;<br /> t:=fa[i];k:=t;right(k);<br /> end;<br />end;</p><p>procedure link(a,b,cc:longint);<br />begin inc(t);next[t]:=d[a];d[a]:=t;p[t]:=b;c[t]:=cc end;</p><p>procedure dfs(i,f:longint);var k:longint;<br />begin<br /> fa[i]:=f;root[i]:=true;ff[i]:=false;<br /> k:=d[i];l[i]:=0;r[i]:=0;<br /> while k<>0 do begin<br /> if p[k]<>f then begin<br /> e[(k+1)>>1]:=p[k];w[p[k]]:=c[k];<br /> min[p[k]]:=c[k];max[p[k]]:=c[k];<br /> dfs(p[k],i);<br /> end;k:=next[k];<br /> end;<br />end;</p><p>begin<br /> readln(task);<br /> for task:=1 to task do begin<br /> readln(n);t:=0;<br /> fillchar(d,sizeof(d),0);<br /> max[0]:=-(1<<30);min[0]:=-max[0];<br /> for i:=2 to n do begin<br /> readln(a,b,cc);<br /> link(a,b,cc);link(b,a,cc);<br /> end;<br /> dfs(1,0);read(q);<br /> while q<>'D' do begin<br /> if q='C' then begin<br /> read(q,q,q,q,q,a,b);a:=e[a];<br /> cut(a,0);w[a]:=b;update(a);<br /> end else<br /> if q='N' then begin<br /> read(q,q,q,q,q,a,b);<br /> access(a);access(b);<br /> fan(g);cut(t,0);fan(g);<br /> end else<br /> if q='Q' then begin<br /> read(q,q,q,q,a,b);<br /> access(a);access(b);<br /> ans:=max[g];cut(t,0);<br /> if ans<max[g] then ans:=max[g];<br /> writeln(ans);<br /> end;<br /> readln;read(q);<br /> end;readln;<br /> end;<br />end.