月下“毛景树”
2010-09-18 17:25
99 查看
bzoj1984
搞了我好久好久好久好久才ac的。。
差不多昨天4小时+今天的2小时。。
这题还是差点破300行。。。
由于我不会树链剖分,所以就用了link-cut-tree。。。鉴于link-cut-tree的常数实在太大了,荣幸的成为ac程序中速度最慢的。。
总耗时7777ms。。。
这题麻烦的就是标记传递
由于linkcuttree是从下往上splay。。
每次在splay的时候。。从需要splay的节点向上到根一遍传递下来
我一开怕tle。。想了很久有什么新方法。。神牛教诲说因为ROtate常数是在太大了,所以要怎么做都可以。。。。所以就那样做。。
我还看了英文论文去看看有没有什么更好的方法。。结论是没有。。
由于他既有集体赋值又有集体增加值的操作。。所以标记会产生冲突。。
因为第一次尝试。所以忽略一些情况。
非常麻烦。。
给每个标记加上一个时间戳。。记录标记先后。。
对于集体赋值操作。。传递后必须把儿子节点的增加值的删除。。。
传递完后把时间戳给删去。。
搞了我好久好久好久好久才ac的。。
差不多昨天4小时+今天的2小时。。
这题还是差点破300行。。。
由于我不会树链剖分,所以就用了link-cut-tree。。。鉴于link-cut-tree的常数实在太大了,荣幸的成为ac程序中速度最慢的。。
总耗时7777ms。。。
这题麻烦的就是标记传递
由于linkcuttree是从下往上splay。。
每次在splay的时候。。从需要splay的节点向上到根一遍传递下来
我一开怕tle。。想了很久有什么新方法。。神牛教诲说因为ROtate常数是在太大了,所以要怎么做都可以。。。。所以就那样做。。
我还看了英文论文去看看有没有什么更好的方法。。结论是没有。。
由于他既有集体赋值又有集体增加值的操作。。所以标记会产生冲突。。
因为第一次尝试。所以忽略一些情况。
非常麻烦。。
给每个标记加上一个时间戳。。记录标记先后。。
对于集体赋值操作。。传递后必须把儿子节点的增加值的删除。。。
传递完后把时间戳给删去。。
program mzn; {$m 100000000} const maxn=100000+1000; inf=maxlongint div 2; var son:Array[0..maxn,0..1]of longint; bian:array[0..maxn*2]of record x,y,ww,num,nexT:longint;end; t1,t2,fa,pt,q,w,max,dep,bj1,bj2,first:array[0..maxn]of longint; bj,ans,tot,n,z:longint; procedure connect(a,b,c,d:longint); begin inc(tot); with bian[tot] do begin x:=a; y:=b; ww:=d; num:=c; nexT:=first[x]; first[x]:=tot; end; end; procedure dfs(X,now:longint); var k:longint; begin k:=first[x]; dep[x]:=now; while k<>0 do with bian[k] do begin if dep[y]=0 then begin w[y]:=ww; fa[y]:=x; pt[num]:=y; dfs(y,now+1); end; k:=next; end; end; procedure init; var w,x,y,z,i:longint; begin readln(n); for i:=1 to n-1 do begin readln(x,y,w); connect(x,y,i,w); connect(y,x,i,w); end; dfs(1,1); end; function bigger(a,b:longint):longint; begin if a>b then exit(a) else exit(B); end; procedure mark(X:longint); begin if bj1[x]<>-inf then begin if (son[x][1]<>0)then begin w[son[x][1]]:=bj1[x]; bj1[son[x][1]]:=bj1[x]; max[son[x][1]]:=bj1[x]; if t1[x]>t2[son[x][1]] then bj2[ son[x][1]]:=0; t1[ son[x][1]]:=bigger(t1[ son[x][1]],t1[x]); end; if (son[x][0]<>0)then begin w[son[x][0]]:=bj1[x]; bj1[son[x][0]]:=bj1[x]; max[son[x][0]]:=bj1[x]; if t1[x]>t2[son[x][0]] then bj2[ son[x][0]]:=0; t1[ son[x][0]]:=bigger(t1[ son[x][0]],t1[x]); end; bj1[x]:=-inf; end; if (bj2[x]<>0)and(t1[x]<t2[x]) then begin if son[x][1]<>0 then begin inc(w[son[x][1]],bj2[x]); inc(max[son[x][1]],bj2[x]); inc(bj2[son[x][1]],bj2[x]); t2[ son[x][1]]:=bigger(t2[ son[x][1]],t2[x]); end; if son[x][0]<>0 then begin inc(w[son[x][0]],bj2[x]); inc(max[son[x][0]],bj2[x]); inc(bj2[son[x][0]],bj2[x]); t2[ son[x][0]]:=bigger(t2[ son[x][0]],t2[x]); end; end; t1[x]:=0; t2[x]:=0; bj2[x]:=0; end; procedure updata(x:longint); begin max[x]:=bigger(max[son[x][1]],max[son[x][0]]); max[x]:=bigger(max[x],w[x]); end; procedure rorate(x,p:longint); var y,z:longint; begin y:=fa[x]; z:=son[x][p]; son[y][1-p]:=z; if z<>0 then fa[z]:=y; fa[x]:=fa[y]; if y=son[fa[y]][0] then son[fa[y]][0]:=x; if y=son[fa[y]][1] then son[fa[y]][1]:=x; fa[y]:=x; son[x][p]:=y; updata(y); end; procedure splay(x:longint); var y,z:longint; begin while (fa[x]<>0)and((x=son[fa[x]][0])or(x=son[fa[x]][1])) do begin y:=fa[x];z:=fa[y]; if (Z=0)or(y<>son[z][0])and(y<>son[z][1]) then if x=son[y][1] then rorate(x,0) else rorate(x,1) else if y=son[z][0] then if x=son[y][0] then begin rorate(y,1);rorate(x,1); end else begin rorate(x,0);rorate(x,1); end else if x=son[y][1] then begin rorate(y,0);rorate(x,0);end else begin rorate(x,1);rorate(x,0);end end; updata(x); end; procedure smark(u:longint); var top,i:longint; begin top:=0; while (fa[u]<>0)and((u=son[fa[u]][0])or(u=son[fa[u]][1])) do begin inc(top); q[top]:=u; u:=fa[u]; end; inc(top); q[top]:=u; for i:=top downto 1 do mark(q[i]); end; procedure access(x,y,t:longint); var u,v:longint; procedure get(v,t:longint); begin mark(v); if t=0 then begin mark(v); w[v]:=z; max[v]:=z; bj1[v]:=z; t1[v]:=bj; end else if t=1 then begin mark(v); inc(w[v],z); inc(max[v],z); inc(bj2[v],z); t2[v]:=bj; end else if ans<max[v] then ans:=max[v]; end; begin if x=y then begin if t=2 then writeln(0); exit; end; u:=x; v:=0; while u<>0 do begin smark(u); splay(u); son[u,1]:=v; updata(u); v:=u;u:=fa[u]; end; u:=y; v:=0; while u<>0 do begin smark(u); splay(u); if fa[u]=0 then begin ans:=-inf; if t<>2 then inc(bj); if v<>0 then get(v,t); if son[u][1]<>0 then get(son[u][1],t); end; son[u,1]:=v; updata(u); v:=u;u:=fa[u]; end; if t=2 then writeln(Ans); end; procedure main; var x,y,i:longint; ch:char; procedure swap(var x,y:longint); var tmp:longint; begin if dep[x]>dep[y] then begin tmp:=x; x:=y; y:=tmp; end; end; procedure readspace; begin while ch<>' ' do read(ch) end; begin for i:=1 to n do begin bj1[i]:=-inf; max[i]:=w[i]; end; read(ch,ch); repeat case ch of 'h':begin readspace; readln(x,y); x:=pt[x]; smark(x); splay(x); w[x]:=y; updata(x); end; 'o':begin readspace; readln(x,y,z); swap(X,y); access(x,y,0); end; 'd':begin readspace; readln(X,y,z); swap(x,y); access(X,y,1); end; 'a':begin readspace; readln(X,y); swap(x,y); access(x,y,2); end; 't':exit; end; read(ch,ch); until 1=2; end; begin init; main; end.
相关文章推荐
- bzoj1984 月下“毛景树”树链剖分 线段树
- BZOJ 1984 月下“毛景树”
- [BZOJ1984]月下“毛景树”(树链剖分)
- 【树链剖分】【分块】【最近公共祖先】【块状树】bzoj1984 月下“毛景树”
- 【BZOJ1984】月下“毛景树”-树链剖分
- [BZOJ1984] 月下“毛景树”
- Bzoj 1984: 月下“毛景树” 树链剖分
- BZOJ1984: 月下“毛景树”
- BZOJ1984 月下“毛景树”
- 1984: 月下“毛景树”
- BZOJ1984月下“毛景树”
- 【bzoj1984】月下“毛景树” 树链剖分+线段树
- 洛谷P4315 月下“毛景树”
- [bzoj1984]月下“毛景树” 树链剖分
- [BZOJ1984]月下“毛景树”解题报告|树链剖分
- BZOJ1984: 月下“毛景树”
- bzoj 1984: 月下“毛景树” 线段树+树链剖分
- bzoj1984 月下“毛景树”(边权的树链剖分)
- 【BZOJ-1984】月下“毛景树” 树链剖分
- bzoj 1984: 月下“毛景树” (树链剖分)