rt,求助,题解里开到 2∗106 都没问题,到我这咋就全 mle 了呢?
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN=2e5+9;
struct Edge{
int nxt,to;
}edge[MAXN];
int num_edge=0,head[MAXN];
int a[MAXN],n,m,root,mods;
int num_T=0;
int top[MAXN],heavy[MAXN],ys[MAXN],Tid[MAXN],siz[MAXN],dep[MAXN],f[MAXN];
int res;
struct Tree{
int ls,rs;
int w,tag;
}tree[MAXN];
int num_tree=1;
void add_edge(int from,int to){
edge[++num_edge]=(Edge){head[from],to};
head[from]=num_edge;
}/**********************************************************************************************/
void push_up(int now){
tree[now].w=tree[tree[now].ls].w+tree[tree[now].rs].w;
}void push_down(int now,int l,int r){
int mid=(l+r)/2;
tree[tree[now].ls].w+=((mid-l+1)*tree[now].tag)%mods;
tree[tree[now].ls].tag+=tree[now].tag;
tree[tree[now].rs].w+=((r-mid)*tree[now].tag)%mods;
tree[tree[now].rs].tag+=tree[now].tag;
tree[now].tag=0;
}void build(int now,int l,int r){
if(l==r){
tree[now].w=ys[l]%mods;
return;
}int mid=(l+r)/2;
tree[now].ls=++num_tree;
tree[now].rs=++num_tree;
build(tree[now].ls,l,mid);
build(tree[now].rs,mid+1,r);
push_up(now);
}void update(int now,int l,int r,int lx,int rx,int k){
if(lx<=l&&r<=rx){
tree[now].w+=((r-l+1)*k)%mods;
tree[now].tag+=k;
return ;
}int mid=(l+r)/2;
push_down(now,l,r);
if(lx<=mid)update(tree[now].ls,l,mid,lx,rx,k);
if(rx>mid)update(tree[now].rs,mid+1,r,lx,rx,k);
push_up(now);
}int query(int now,int l,int r,int lx,int rx){
int ans=0;
if(lx<=l&&r<=rx){
ans+=tree[now].w;
return ans;
}int mid=(l+r)/2;
push_down(now,l,r);
if(lx<=mid)ans+=query(tree[now].ls,l,mid,lx,rx)%mods;
if(rx>mid)ans+=query(tree[now].rs,mid+1,r,lx,rx)%mods;
return ans;
}/**********************************************************************************************/
void dfs1(int now,int fa){
siz[now]=1;
f[now]=fa;
dep[now]=dep[fa]+1;
for(int i=head[now];i;i=edge[i].nxt){
if(edge[i].to==fa)continue;
dfs1(edge[i].to,now);
siz[now]+=siz[edge[i].to];
if(heavy[now]==0||siz[edge[i].to]>siz[heavy[now]])heavy[now]=edge[i].to;
}
}void dfs2(int now,int tp){
top[now]=tp;
Tid[now]=++num_T;
ys[num_T]=a[now];
if(heavy[now])dfs2(heavy[now],tp);
for(int i=head[now];i;i=edge[i].nxt){
if(edge[i].to==f[now])continue;
if(edge[i].to==heavy[now])continue;
dfs2(edge[i].to,edge[i].to);
}
}void Tupdate1(int x,int y,int k){
k%=mods;
while(top[x]!=top[y]){
if(dep[x]<dep[y])swap(x,y);
update(1,1,n,Tid[top[x]],Tid[x],k);
x=f[top[x]];
}if(dep[x]>dep[y])swap(x,y);
update(1,1,n,Tid[x],Tid[y],k);
}void Tupdate2(int x,int k){
k%=mods;
update(1,1,n,Tid[x],Tid[x]+siz[x]-1,k);
}int Tquery1(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[x]<dep[y])swap(x,y);
res=query(1,1,n,Tid[top[x]],Tid[x]);
ans=(ans+res)%mods;
x=f[top[x]];
}if(dep[x]>dep[y])swap(x,y);
res=query(1,1,n,Tid[x],Tid[y]);
ans=(ans+res)%mods;
return ans;
}int Tquery2(int x){
return query(1,1,n,Tid[x],Tid[x]+siz[x]-1)%mods;
}int main(){
scanf("%d %d %d %d",&n,&m,&root,&mods);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n-1;i++){
int u,v;
scanf("%d %d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}dfs1(root,0);
dfs2(root,root);
build(1,1,n);
for(int i=1;i<=m;i++){
int op,x,y,k;
scanf("%d",&op);
if(op==1){
scanf("%d %d %d",&x,&y,&k);
Tupdate1(x,y,k);
}else if(op==2){
scanf("%d %d",&x,&y);
printf("%d\n",Tquery1(x,y)%mods);
}else if(op==3){
scanf("%d %d",&x,&k);
Tupdate2(x,k);
}else if(op==4){
scanf("%d",&x);
printf("%d\n",Tquery2(x)%mods);
}
}
return 0;
}