acm归来
应该说又是一次铩羽,发现其他高中的队伍普遍在我们前面,雅礼包揽了前2,我们高三神牛只拿了第6,然后就是我们uracil排到了22位,主要是c题依poj的习惯打了not seekeof
结果测评器不认账,死活报wa,然后就是g题,题目数据范围有问题,结果不告诉我们,足足花了2个半小时,在2:30即将下考时才ac,但是本来可以再a一道动规的,结果没时间不说,罚时罚的想吐,排在了sol 6的最后一名。
poj 2763应该可以算是动态树问题,但是我用欧拉序列+线段树给过了(其实我发现网上普遍也是用这种算法)
给你n个节点的带权树,m个操作,当前位置为s
每个操作:0 x 从当前节点移动到x,并输出距离
1 x y 修改第x条边权值为y
dist=dist[s]+dist[x]-2*dist[lca(s,x)];dist指到根的距离。
我们构造一个欧拉序列(使每棵子树的开头和末尾均为根),当某条边权值被改变,即在这棵子树中每个节点dist值均+(w‘-w),因此我们用线段树维护,每次标记永久化(或加时间戳)进行区间修改,求dist回收标记即可。
lca tarjan,rmq均可。
var tail:array[1..100000]of longint;
next,sora,cost:array[1..500000]of longint;
root,l,r,pp,pos,pos2,d,ww:array[0..100000]of longint;
di:array[1..524288]of longint;
f:array[1..500000,0..20]of longint;
o:array[0..20]of longint;
len,n,m,m1,ss,dep,ll:longint;
function min(x,y:longint):longint;
begin
if d[x]<d[y] then exit(x) else exit(y)
end;
procedure dfs(x,y,w:longint);
var i,ne:longint;
begin
root[x]:=y;
inc(dep);inc(ll);pp[x]:=ll;d[x]:=dep;f[ll,0]:=x;
inc(len);di[len+m1]:=w;l[x]:=len;
i:=x;
while next[i]<>0 do begin
i:=next[i];ne:=sora[i];
if ne<>y then dfs(ne,x,w+cost[i]);
inc(ll);f[ll,0]:=x
end;
inc(len);di[len+m1]:=w;r[x]:=len
end;
function dis(x:longint):longint;
begin
x:=x+m1;dis:=0;
while x<>0 do begin
dis:=dis+di[x];
x:=x>>1
end
end;
procedure note(l,r,w:longint);
begin
l:=l+m1-1;r:=r+m1+1;
while not(l xor r=1) do begin
if l and 1=0 then di[l+1]:=di[l+1]+w;
if r and 1=1 then di[r-1]:=di[r-1]+w;
l:=l>>1;r:=r>>1
end
end;
procedure origin;
var i:longint;
begin
m1:=1;
while m1<n<<1+2 do m1:=m1<<1;m1:=m1-1;
for i:=1 to n do tail[i]:=i;ss:=n;
end;
procedure link(x,y,z:longint);
begin
inc(ss);next[tail[x]]:=ss;tail[x]:=ss;sora[ss]:=y;cost[ss]:=z;
inc(ss);next[tail[y]]:=ss;tail[y]:=ss;sora[ss]:=x;cost[ss]:=z
end;
procedure rmq;
var i,j,k:longint;
begin
o[0]:=1;
for i:=1 to 20 do o[i]:=o[i-1]<<1;
k:=trunc(ln(ll)/ln(2));
for j:=1 to k do
for i:=1 to ll do
if i+o[j]-1<=ll then f[i,j]:=min(f[i,j-1],f[i+o[j-1],j-1])
else break
end;
procedure init;
var i,x,y,z,ch,s,lll,rrr,lca,ans,w,ans1,ans2,ans3,k:longint;
begin
readln(n,m,s);
origin;
for i:=1 to n-1 do begin
readln(x,y,z);pos[i]:=y;pos2[i]:=x;ww[i]:=z;
link(x,y,z)
end;
d[0]:=maxlongint;dep:=0;ll:=0;
dfs(s,0,0);
rmq;
for i:=1 to m do begin
read(ch);
if ch=0 then begin
readln(x);
if pp[x]<pp[s] then begin lll:=pp[x];rrr:=pp[s] end else begin lll:=pp[s];rrr:=pp[x] end;
k:=trunc(ln(rrr-lll+1)/ln(2));
lca:=min(f[lll,k],f[rrr-o[k]+1,k]);
ans1:=dis(l[x]);ans2:=dis(l[s]);ans3:=dis(l[lca]);
ans:=ans1+ans2-2*ans3;
writeln(ans);
s:=x
end
else begin
readln(x,w);
if root[pos[x]]=pos2[x] then lll:=pos[x] else lll:=pos2[x];
note(l[lll],r[lll],w-ww[x]);
ww[x]:=w
end
end;
end;
begin
assign(input,'2763.in');reset(input);
assign(output,'2763.out');rewrite(output);
init;
close(input);close(output)
end.