动态修改询问树上两点距离 poj2763

来源:互联网 发布:软件开发体系 编辑:程序博客网 时间:2024/05/19 10:39

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]:=lenend;function dis(x:longint):longint;begin x:=x+m1;dis:=0; while x<>0 do begin  dis:=dis+di[x];  x:=x>>1 endend;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 endend;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]:=zend;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 breakend;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;beginassign(input,'2763.in');reset(input);assign(output,'2763.out');rewrite(output); init;close(input);close(output)end.