CODE[VS]4633:Mz树链剖分练习
Description
给定一棵结点数为n的树,初始点权均为0,有依次q个操作,每次操作有三个参数a,b,c,当a=1时,表示给b号结点到c号结点路径上的所有点(包括b,c,下同)权值都增加1,当a=2时,表示询问b号结点到c号结点路径上的所有点权值之和。
Input
第一行,一个正整数n。
接下来n-1行,每行一对正整数x,y,表示x号结点和y号结点之间有一条边。
第n+1行,一个正整数q。
最后q行,每行一组正整数a,b,c,表示操作的三个参数。b和c可能相等。
保证数据都是合法的。
Output
若干行,每行一个非负整数表示答案。
Sample Input
5
1 2
2 3
1 4
2 5
5
1 4 5
2 1 5
1 1 3
2 5 3
2 4 3
Sample Output
3
4
6
题解:
如题名,数剖练习题。
代码:
1 var 2 son,siz,dep,top,w,fa,tt2,c,flag:array[-1..200001]of longint; 3 tt:array[-1..400001,-2..2]of longint; 4 b:array[-1..200001,1..2]of longint; 5 i,j,k,l,n,m,totw,q,t:longint; 6 function cc2(x,l,r:longint):longint; 7 begin 8 cc2:=0; cc2:=cc2+(r-l+1)*tt[x,0]; 9 if tt[x,1]=tt[x,2] then exit; 10 if r<=(tt[x,1]+tt[x,2])div 2 then cc2:=cc2+cc2(tt[x,-1],l,r)else 11 if l>(tt[x,1]+tt[x,2])div 2 then cc2:=cc2+cc2(tt[x,-2],l,r)else 12 begin cc2:=cc2+cc2(tt[x,-1],l,(tt[x,1]+tt[x,2])div 2); 13 cc2:=cc2+cc2(tt[x,-2],((tt[x,1]+tt[x,2])div 2)+1,r); end; 14 end; 15 procedure cc1(x,l,r:longint); 16 begin 17 if(l=tt[x,1])and(r=tt[x,2])then 18 begin tt[x,0]:=tt[x,0]+1; exit; end; 19 if r<=(tt[x,1]+tt[x,2])div 2 then cc1(tt[x,-1],l,r)else 20 if l>(tt[x,1]+tt[x,2])div 2 then cc1(tt[x,-2],l,r)else 21 begin cc1(tt[x,-1],l,(tt[x,1]+tt[x,2])div 2); 22 cc1(tt[x,-2],((tt[x,1]+tt[x,2])div 2)+1,r); end; 23 end; 24 procedure ss(z,x,y:longint); 25 var i,j,k,l,f1,f2,tot:longint; 26 begin 27 f1:=top[x]; f2:=top[y]; tot:=0; 28 while f1<>f2 do 29 begin 30 if dep[f1]<dep[f2] then 31 begin j:=f1; f1:=f2; f2:=j; j:=x; x:=y; y:=j; end; 32 if z=1 then cc1(1,w[f1],w[x])else 33 tot:=tot+cc2(1,w[f1],w[x]); x:=fa[f1]; f1:=top[x]; 34 end; 35 if w[x]>w[y] then begin j:=x; x:=y; y:=j; end; 36 if z=1 then cc1(1,w[x],w[y])else 37 begin tot:=tot+cc2(1,w[x],w[y]); writeln(tot); end; 38 end; 39 procedure dfs2(x:longint); 40 var i,j,k,l:longint; 41 begin 42 j:=c[x]; 43 while b[j,1]=x do 44 begin 45 if b[j,2]=son[x] then 46 begin 47 flag[b[j,2]]:=1; top[b[j,2]]:=top[x]; 48 inc(totw); w[b[j,2]]:=totw; tt2[totw]:=b[j,2]; 49 dfs2(b[j,2]); 50 end; 51 inc(j); 52 end; 53 j:=c[x]; 54 while b[j,1]=x do 55 begin 56 if flag[b[j,2]]=0 then 57 begin 58 flag[b[j,2]]:=1; top[b[j,2]]:=b[j,2]; 59 inc(totw); w[b[j,2]]:=totw; tt2[totw]:=b[j,2]; 60 dfs2(b[j,2]); 61 end; 62 inc(j); 63 end; 64 end; 65 procedure dfs1(x:longint); 66 var i,j,k,l:longint; 67 begin 68 j:=c[x]; siz[x]:=1; 69 while b[j,1]=x do 70 begin 71 if fa[b[j,2]]=0 then 72 begin 73 fa[b[j,2]]:=x; 74 dep[b[j,2]]:=dep[x]+1; 75 dfs1(b[j,2]); siz[x]:=siz[x]+siz[b[j,2]]; 76 if(son[x]=0)or(siz[son[x]]<siz[b[j,2]])then 77 son[x]:=b[j,2]; 78 end; 79 inc(j); 80 end; 81 end; 82 procedure sort(l,r:longint); 83 var 84 i,j,x,x2:longint; 85 y:array[1..2]of longint; 86 begin 87 i:=l; j:=r; 88 x:=b[(l+r)div 2,1]; 89 x2:=b[(l+r)div 2,2]; 90 repeat 91 while(b[i,1]<x)or((b[i,1]=x)and(b[i,2]<x2))do inc(i); 92 while(x<b[j,1])or((b[j,1]=x)and(b[j,2]>x2))do dec(j); 93 if not(i>j) then 94 begin 95 y:=b[i]; 96 b[i]:=b[j]; 97 b[j]:=y; 98 inc(i); 99 j:=j-1; 100 end; 101 until i>j; 102 if l<j then sort(l,j); 103 if i<r then sort(i,r); 104 end; 105 procedure make(l,r:longint); 106 var i,j,k:longint; 107 begin 108 inc(t); i:=t; tt[i,1]:=l; tt[i,2]:=r; 109 if l<>r then 110 begin 111 tt[i,-1]:=t+1; make(l,(l+r)div 2); 112 tt[i,-2]:=t+1; make(((l+r)div 2)+1,r); 113 end; 114 end; 115 begin 116 readln(n); m:=(n-1)*2; 117 for i:=1 to n-1 do 118 begin 119 readln(b[i*2-1,1],b[i*2-1,2]); 120 b[i*2,1]:=b[i*2-1,2]; b[i*2,2]:=b[i*2-1,1]; 121 end; 122 sort(1,m); j:=1; 123 for i:=1 to n do 124 begin 125 if j>m then break; 126 if b[j,1]>i then continue; 127 c[i]:=j; while b[j,1]=i do inc(j); 128 end; 129 dep[1]:=1; fa[1]:=-1; dfs1(1); 130 totw:=1; top[1]:=1; tt2[1]:=1; w[1]:=1; flag[1]:=1; dfs2(1); 131 t:=0; make(1,n); 132 readln(q); 133 for i:=1 to q do 134 begin 135 readln(j,k,l); 136 ss(j,k,l); 137 end; 138 end.