#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i(j);i!=(k+1);++i)
using namespace std;
typedef long long ll;
const int AN=1e6;
inline void read(int &x) {
x=0;
register char ch=getchar();
int w=0;
while(ch>'9'||ch<'0') {
w|=ch=='-';
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=x*10+ch-48;
ch=getchar();
}
w?x=~(x-1):x;
}
int N,M,P;
int b[AN],a[AN];
int size[AN],son[AN],dfn[AN],num,dep[AN],fa[AN];
int top[AN];
struct graph {
int head[AN],next[AN],tot,ver[AN];
inline void add(int a,int b) {
ver[++tot]=b;
next[tot]=head[a];
head[a]=tot;
}
} G;
struct Segmentree {
int lc[AN<<1],rc[AN<<1],cnt,sum[AN<<1],root,lazy[AN<<1];
// Segmentree() {
// memset(lazy,0xff,sizeof lazy);
// root=cnt=0;
// }
// inline void spread(int p,int L,int R) {
//// if(lazy[p]==-1) return;
// if(lazy[p]==0) return ;
// int mid=(L+R)>>1;
// if(lc[p]) {
// lazy[lc[p]]=lazy[p];
// sum[lc[p]]+=((mid-L+1)*lazy[p])%P;
// }
// if(rc[p]) {
// lazy[rc[p]]=lazy[p];
// sum[rc[p]]+=((R-mid)*lazy[p])%P;
// }
// lazy[p]=0;
//// lazy[p]=-1;
// }
inline void spread(int p,int L,int R) {
if(!lazy[p]) return ;
if(!lc[p]) lc[p]=++cnt;
if(!rc[p]) rc[p]=++cnt;
int mid=(L+R)>>1;
sum[lc[p]]+=(mid-L+1)*lazy[p];
sum[rc[p]]+=(R-mid)*lazy[p];
lazy[rc[p]]+=lazy[p];
lazy[lc[p]]+=lazy[p];
lazy[p]=0;
}
inline void insert(int &p,int L,int R,int ll,int rr,int v) {
if(!p) p=++cnt;
spread(p,L,R);
if(ll<=L&&rr>=R) {
sum[p]+=((R-L+1)*v)%P;
lazy[p]+=v;
return;
}
int mid=(L+R)>>1;
if(ll<=mid)insert(lc[p],L,mid,ll,rr,v);
if(rr>mid) insert(rc[p],mid+1,R,ll,rr,v);
sum[p]=(sum[lc[p]]+sum[rc[p]])%P;
}
inline int query(int p,int L,int R,int ll,int rr) {
if(!p) return 0;
spread(p,L,R);
if(ll<=L&&rr>=R) {
return sum[p];
}
int mid=(L+R)>>1;
int val(0);
if(ll<=mid) val+=query(lc[p],L,mid,ll,rr)%P;
if(rr>mid) val+=query(rc[p],mid+1,R,ll,rr)%P;
return val%P;
}
} S;
inline int dfs1(int x,int fath) {
dep[x]=dep[fath]+1;
fa[x]=fath;
size[x]=1;
int maxson=-1;
for(register int i(G.head[x]); i; i=G.next[i]) {
int y=G.ver[i];
if(y==fath) continue;
dfs1(y,x);
size[x]+=size[y];
if(size[y]>maxson) maxson=size[y],son[x]=y;
}
}
inline void dfs2(int x,int topf) {
dfn[x]=++num;
a[num]=b[x];
top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);
for(register int i(G.head[x]); i; i=G.next[i]) {
int y=G.ver[i];
if(dfn[y]) continue;
dfs2(y,y);
}
}
inline int querychain(int x,int y) {
int sum(0);
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
sum=(sum+S.query(S.root,1,N,dfn[top[x]],dfn[x]) )%P;
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
sum=(sum+S.query(S.root,1,N,dfn[x],dfn[y]))%P;
return sum;
}
inline void changechain(int x,int y,int k) {
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
S.insert(S.root,1,N,dfn[top[x]],dfn[x],k);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
S.insert(S.root,1,N,dfn[x],dfn[y],k);
}
int main() {
int R;
read(N);
read(M);
read(R);
read(P);
rep(i,1,N) read(b[i]);
rep(i,1,N-1) {
int x,y;
read(x);
read(y);
G.add(x,y);
G.add(y,x);
}
dfs1(R,0);
dfs2(R,R);
cout<<"----"<<endl;
rep(i,1,N) cout<<dfn[i]<<' '<<a[dfn[i]]<<endl;
rep(i,1,N) S.insert(S.root,1,N,dfn[i],dfn[i],a[dfn[i]]);
cout<<S.sum[1]<<endl;
// cout<<dfn[R]<<' '<<size[R]<<endl;
// cout<<S.query(S.root,1,N,1,dfn[2]+size[2]-1);
// rep(i,1,N) cout<<S.query(S.root,1,N,dfn[i],dfn[i]+size[i]-1)<<' ';
// rep(i,1,N) cout<<size[i]<<'\n';
// rep(i,1,N) cout<<dfn[i]<<'\n';
// rep(i,1,N) cout<<a[i]<<'\n';
// rep(i,1,N) cout<<dep[i]<<'\n';
// int op,x,y,z;
// while(M--) {
// read(op);
// if(op==1) {
// read(x);
// read(y);
// read(z);
// changechain(x,y,z%P);
// } else if(op==2) {
// read(x);
// read(y);
// cout<<querychain(x,y)%P<<'\n';
// } else if(op==3) {
// read(x);
// read(z);
// S.insert(S.root,1,N,dfn[x],dfn[x]+size[x]-1,z%P);
// } else if(op==4) {
// read(x);
// cout<<S.query(S.root,1,N,dfn[x],dfn[x]+size[x]-1)<<'\n';
// }
// }
return 0;
}
/*
5 5 2 24
7 3 7 8 0
1 2
1 5
3 1
4 1
3 4 2
3 2 2
4 5
1 5 1 3
2 1 3
*/
初始化查询整棵树的和就错了,,输出1。。。。