树链剖分入门

声明

 


 

      树链剖分前置知识:链式前向星、线段树。

 

    模板题:洛谷 P3384 

 


 

    这里就转载别人的博客吧(内含C++标程)~

 

      
  1 type
  2         tree=record
  3                 data,delta,l,r:longint;
  4         end;
  5 var
  6         t:array[0..300001] of tree;
  7         size,fa,deep,son,top,dfn,a,rank,en,first,next:array[0..200001] of longint;
  8         cnt,tot,n,m,i,r,p,x,y,z,k:longint;
  9 procedure add(x,y:longint);
 10 begin
 11         inc(cnt);
 12         next[cnt]:=first[x];
 13         first[x]:=cnt;
 14         en[cnt]:=y;
 15 end;
 16 procedure down(tot:longint);
 17 begin
 18         t[tot*2].data:=(t[tot*2].data+t[tot].delta*(t[tot*2].r-t[tot*2].l+1) mod p) mod p;
 19         t[tot*2+1].data:=(t[tot*2+1].data+t[tot].delta*(t[tot*2+1].r-t[tot*2+1].l+1) mod p) mod p;
 20         t[tot*2].delta:=(t[tot*2].delta+t[tot].delta) mod p;
 21         t[tot*2+1].delta:=(t[tot*2+1].delta+t[tot].delta) mod p;
 22         t[tot].delta:=0;
 23 end;
 24 procedure dfs1(x,f:longint);
 25 var
 26         t,e:longint;
 27 begin
 28         fa[x]:=f;
 29         deep[x]:=deep[f]+1;
 30         size[x]:=1;
 31         t:=first[x];
 32         while t<>0 do
 33         begin
 34                 e:=en[t];
 35                 if e<>f then
 36                 begin
 37                         dfs1(e,x);
 38                         inc(size[x],size[e]);
 39                         if (son[x]=0) or (size[e]>size[son[x]]) then son[x]:=e;
 40                 end;
 41                 t:=next[t];
 42         end;
 43 end;
 44 procedure dfs2(x,f:longint);
 45 var
 46         t,e:longint;
 47 begin
 48         inc(tot);
 49         dfn[x]:=tot;
 50         top[x]:=f;
 51         rank[tot]:=x;
 52         if son[x]=0 then exit;
 53         dfs2(son[x],f);
 54         t:=first[x];
 55         while t<>0 do
 56         begin
 57                 e:=en[t];
 58                 if (e<>son[x]) and (e<>fa[x]) then dfs2(e,e);
 59                 t:=next[t];
 60         end;
 61 end;
 62 procedure build(tot,l,r:longint);
 63 var
 64         mid:longint;
 65 begin
 66         if l=r then
 67         begin
 68                 t[tot].data:=a[rank[l]] mod p;
 69                 t[tot].l:=l;
 70                 t[tot].r:=r;
 71                 exit;
 72         end;
 73         t[tot].l:=l;
 74         t[tot].r:=r;
 75         mid:=(t[tot].l+t[tot].r) div 2;
 76         build(tot*2,l,mid);
 77         build(tot*2+1,mid+1,r);
 78         t[tot].data:=(t[tot*2].data+t[tot*2+1].data) mod p;
 79 end;
 80 procedure changesubtree(l,r,c,tot:longint);
 81 var
 82         mid:longint;
 83 begin
 84         if (l<=t[tot].l) and (t[tot].r<=r) then
 85         begin
 86                 t[tot].data:=(t[tot].data+c*(t[tot].r-t[tot].l+1) mod p) mod p;
 87                 t[tot].delta:=(t[tot].delta+c) mod p;
 88                 exit;
 89         end;
 90         mid:=(t[tot].l+t[tot].r) div 2;
 91         if t[tot].delta<>0 then down(tot);
 92         if l<=mid then changesubtree(l,r,c,tot*2);
 93         if r>mid then changesubtree(l,r,c,tot*2+1);
 94         t[tot].data:=(t[tot*2].data+t[tot*2+1].data) mod p;
 95 end;
 96 function querysubtree(l,r,tot:longint):longint;
 97 var
 98         mid:longint;
 99 begin
100         if (l<=t[tot].l) and (t[tot].r<=r) then exit(t[tot].data);
101         mid:=(t[tot].l+t[tot].r) div 2;
102         if t[tot].delta<>0 then down(tot);
103         querysubtree:=0;
104         if l<=mid then querysubtree:=(querysubtree+querysubtree(l,r,tot*2)) mod p;
105         if r>mid then querysubtree:=(querysubtree+querysubtree(l,r,tot*2+1)) mod p;
106 end;
107 procedure changeedge(x,y,c:longint);
108 begin
109         while top[x]<>top[y] do
110                 if deep[top[x]]>=deep[top[y]] then
111                 begin
112                         changesubtree(dfn[top[x]],dfn[x],c,1);
113                         x:=fa[top[x]];
114                 end else
115                 begin
116                         changesubtree(dfn[top[y]],dfn[y],c,1);
117                         y:=fa[top[y]];
118                 end;
119         if dfn[x]<=dfn[y] then changesubtree(dfn[x],dfn[y],c,1)
120                 else changesubtree(dfn[y],dfn[x],c,1);
121 end;
122 function queryedge(x,y:longint):longint;
123 begin
124         queryedge:=0;
125         while top[x]<>top[y] do
126                 if deep[top[x]]>=deep[top[y]] then
127                 begin
128                         queryedge:=(queryedge+querysubtree(dfn[top[x]],dfn[x],1)) mod p;
129                         x:=fa[top[x]];
130                 end else
131                 begin
132                         queryedge:=(queryedge+querysubtree(dfn[top[y]],dfn[y],1)) mod p;
133                         y:=fa[top[y]];
134                 end;
135         if dfn[x]<=dfn[y] then queryedge:=(queryedge+querysubtree(dfn[x],dfn[y],1)) mod p
136                 else queryedge:=(queryedge+querysubtree(dfn[y],dfn[x],1)) mod p;
137 end;
138 begin
139         readln(n,m,r,p);
140         for i:=1 to n do
141                 read(a[i]);
142         readln;
143         for i:=1 to n-1 do
144         begin
145                 readln(x,y);
146                 add(x,y);
147                 add(y,x);
148         end;
149         dfs1(r,0);
150         dfs2(r,r);
151         build(1,1,n);
152         for i:=1 to m do
153         begin
154                 read(k);
155                 if k=1 then
156                 begin
157                         readln(x,y,z);
158                         changeedge(x,y,z);
159                 end else if k=2 then
160                 begin
161                         readln(x,y);
162                         writeln(queryedge(x,y));
163                 end else if k=3 then
164                 begin
165                         readln(x,z);
166                         changesubtree(dfn[x],dfn[x]+size[x]-1,z,1);
167                 end else
168                 begin
169                         readln(x);
170                         writeln(querysubtree(dfn[x],dfn[x]+size[x]-1,1));
171                 end;
172         end;
173 end.
然后附 Pascal 标程

 

posted @ 2019-08-08 10:11  》落雨~·~情缘《  阅读(144)  评论(0编辑  收藏  举报