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.