树链剖分前置知识:链式前向星、线段树。
模板题:洛谷 P3384
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.