您的位置:首页 > 其它

月下“毛景树”

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常数是在太大了,所以要怎么做都可以。。。。所以就那样做。。

我还看了英文论文去看看有没有什么更好的方法。。结论是没有。。

由于他既有集体赋值又有集体增加值的操作。。所以标记会产生冲突。。

因为第一次尝试。所以忽略一些情况。

非常麻烦。。

给每个标记加上一个时间戳。。记录标记先后。。

对于集体赋值操作。。传递后必须把儿子节点的增加值的删除。。。

传递完后把时间戳给删去。。

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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: