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.
View Code
原文地址:https://www.cnblogs.com/GhostReach/p/6257499.html