1 type 2 rec =record 3 l,r :longint; 4 sum,lazy :int64; 5 end; 6 7 8 var 9 n,m,r,mo,i,x,y,z,opt,tot,ll :longint; 10 pre,last,other :array[0..200050] of longint; 11 num :array[0..100050] of longint; 12 a,key :array[0..100050] of int64; 13 t :Array[0..300050] of rec; 14 size,top,dep,father :array[0..100050] of longint; 15 vis :Array[0..100050] of boolean; 16 mson :Array[0..100050] of longint; 17 18 procedure swap(var x,y:longint); 19 var 20 z :longint; 21 begin 22 z:=x; 23 x:=y; 24 y:=z; 25 end; 26 27 procedure add(u,v:longint); 28 begin 29 inc(ll); 30 pre[ll]:=last[u]; 31 last[u]:=ll; 32 other[ll]:=v; 33 end; 34 35 procedure dfs(x:longint); 36 var 37 p,q :longint; 38 begin 39 size[x]:=1; 40 p:=last[x]; 41 while p<>0 do 42 begin 43 q:=other[p]; 44 if not vis[q] then 45 begin 46 father[q]:=x; 47 vis[q]:=true; 48 dfs(q); 49 inc(size[x],size[q]); 50 if size[mson[x]]<size[q] then mson[x]:=q; 51 end; 52 p:=pre[p]; 53 end; 54 end; 55 56 procedure make(x,topp,depp:longint); 57 var 58 p,q :longint; 59 begin 60 inc(tot); 61 num[x]:=tot; 62 a[tot]:=key[x]; 63 top[x]:=topp; 64 dep[x]:=depp; 65 if mson[x]<>0 then 66 begin 67 vis[mson[x]]:=true; 68 make(mson[x],topp,depp); 69 end; 70 p:=last[x]; 71 while p<>0 do 72 begin 73 q:=other[p]; 74 if (not vis[q]) and (q<>mson[x]) then 75 begin 76 vis[q]:=true; 77 make(q,q,depp+1); 78 end; 79 p:=pre[p]; 80 end; 81 end; 82 83 procedure build(x,l,r:longint); 84 var 85 mid :longint; 86 begin 87 t[x].l:=l; t[x].r:=r; 88 if (t[x].l=t[x].r) then 89 begin 90 t[x].sum:=a[l] mod mo; 91 exit; 92 end; 93 mid:=(t[x].l+t[x].r)>>1; 94 build(x*2,l,mid); 95 build(x*2+1,mid+1,r); 96 t[x].sum:=(t[x*2].sum+t[x*2+1].sum) mod mo; 97 end; 98 99 procedure update(x:longint); 100 begin 101 t[x].sum:=(t[x].sum+t[x].lazy*(t[x].r-t[x].l+1)) mod mo; 102 if t[x].l=t[x].r then 103 begin 104 t[x].lazy:=0; 105 exit; 106 end; 107 t[x*2].lazy:=(t[x*2].lazy+t[x].lazy) mod mo; 108 t[x*2+1].lazy:=(t[x*2+1].lazy+t[x].lazy) mod mo; 109 t[x].lazy:=0; 110 end; 111 112 procedure change(x,l,r,y:longint); 113 var 114 mid :longint; 115 begin 116 if (t[x].l=l) and (t[x].r=r) then 117 begin 118 t[x].lazy:=(t[x].lazy+y) mod mo; 119 exit; 120 end; 121 if t[x].lazy<>0 then update(x); 122 mid:=(t[x].l+t[x].r)>>1; 123 if l>mid then change(x*2+1,l,r,y) else 124 if r<=mid then change(x*2,l,r,y) else 125 begin 126 change(x*2,l,mid,y); 127 change(x*2+1,mid+1,r,y); 128 end; 129 t[x].sum:=(t[x*2].sum+t[x*2+1].sum+t[x*2].lazy*(t[x*2].r-t[x*2].l+1)+t[x*2+1].lazy*(t[x*2+1].r-t[x*2+1].l+1)) mod mo; 130 end; 131 132 function find(x,l,r:longint):longint; 133 var 134 mid :longint; 135 begin 136 if t[x].lazy<>0 then update(x); 137 if (t[x].l=l) and (t[x].r=r) then exit(t[x].sum); 138 mid:=(t[x].l+t[x].r)>>1; 139 if l>mid then exit(find(x*2+1,l,r)) else 140 if r<=mid then exit(find(x*2,l,r)) else 141 exit((find(x*2,l,mid)+find(x*2+1,mid+1,r)) mod mo); 142 end; 143 144 procedure qchan(x,y,z:longint); 145 begin 146 if dep[x]>dep[y] then swap(x,y); 147 while dep[x]<dep[y] do 148 begin 149 change(1,num[top[y]],num[y],z); 150 y:=father[top[y]]; 151 end; 152 while top[x]<>top[y] do 153 begin 154 change(1,num[top[x]],num[x],z); 155 change(1,num[top[y]],num[y],z); 156 x:=father[top[x]]; 157 y:=father[top[y]]; 158 end; 159 x:=num[x]; 160 y:=num[y]; 161 if x>y then swap(x,y); 162 change(1,x,y,z); 163 end; 164 165 function qfind(x,y:longint):int64; 166 var 167 ans :int64; 168 begin 169 ans:=0; 170 if dep[x]>dep[y] then swap(x,y); 171 while dep[x]<dep[y] do 172 begin 173 ans:=(ans+find(1,num[top[y]],num[y])) mod mo; 174 y:=father[top[y]]; 175 end; 176 while top[x]<>top[y] do 177 begin 178 ans:=(ans+find(1,num[top[x]],num[x])) mod mo; 179 ans:=(ans+find(1,num[top[y]],num[y])) mod mo; 180 x:=father[top[x]]; 181 y:=father[top[y]]; 182 end; 183 x:=num[x]; 184 y:=num[y]; 185 if x>y then swap(x,y); 186 ans:=(ans+find(1,x,y)) mod mo; 187 writeln(ans); 188 end; 189 190 begin 191 read(n,m,r,mo); 192 for i:=1 to n do read(key[i]); 193 for i:=1 to n-1 do 194 begin 195 read(x,y); 196 add(x,y); 197 add(y,x); 198 end; 199 vis[r]:=true; 200 dfs(r); 201 fillchar(vis,sizeof(vis),false); 202 vis[r]:=true; 203 make(r,r,1); 204 build(1,1,n); 205 for i:=1 to m do 206 begin 207 read(opt); 208 if opt=1 then 209 begin 210 read(x,y,z); 211 qchan(x,y,z); 212 end else 213 if opt=2 then 214 begin 215 read(x,y); 216 qfind(x,y); 217 end else 218 if opt=3 then 219 begin 220 read(x,y); 221 change(1,num[x],num[x]+size[x]-1,y); 222 end else 223 begin 224 read(x); 225 writeln(find(1,num[x],num[x]+size[x]-1)); 226 end; 227 end; 228 end. 229 230