STARSczy @ 2023-09-12 23:02:39
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=2e5+10;
inline int read(){
int c,w=0,n=0;
while((c=getchar())<'0'||'9'<c) w=c=='-';
do n=n*10+c-'0';while('0'<=(c=getchar())&&c<='9');
return w?-n:n;
}
inline int write(int n){
if(n<0) putchar('-'),n=-n;
if(n>9) write(n/10);
putchar(n%10+'0');
return n;
}
int n=read(),m=read(),root=read(),mod=read(),top,a[maxn];
struct tree{
struct node{int l,r,data,lazy;}a[maxn<<2];
void init(int id,int l,int r,int *p){
a[id].l=l,a[id].r=r;
if(l>=r){
a[id].data=*(p+l);
return;
}
int mid=(l+r)>>1;
init(id<<1,l,mid,p);
init(id<<1|1,mid+1,r,p);
a[id].data=a[id<<1].data+a[id<<1|1].data;
}
void down(int id){
if(!a[id].lazy) return;
a[id].data+=a[id].lazy*(a[id].r-a[id].l+1);
a[id<<1].lazy+=a[id].lazy;
a[id<<1|1].lazy+=a[id].lazy;
a[id].lazy=0;
}
void update(int id){
a[id].data=
a[id<<1].data+a[id<<1].lazy*(a[id<<1].r-a[id<<1].l+1)+
a[id<<1|1].data+a[id<<1|1].lazy*(a[id<<1|1].r-a[id<<1|1].l+1);
}
void change(int id,int l,int r,int add){
cout<<l<<","<<r<<"]";
if(a[id].l==l&&a[id].r==r){
a[id].lazy+=add;
return;
}
down(id);
if(a[id<<1].r<l) change(id<<1|1,l,r,add);
else if(a[id<<1|1].l>r) change(id<<1,l,r,add);
else{
change(id<<1,l,a[id<<1].r,add);
change(id<<1|1,a[id<<1|1].l,r,add);
}
update(id);
}
int sum(int id,int l,int r){
if(a[id].l==l&&a[id].r==r){
return a[id].data+a[id].lazy*(a[id].r-a[id].l+1);
}
down(id);
if(a[id<<1|1].l>r) return sum(id<<1,l,r);
if(a[id<<1].r<l) return sum(id<<1|1,l,r);
return sum(id<<1,l,a[id<<1].r)+sum(id<<1|1,a[id<<1|1].l,r);
}
}t;
struct node{int size,data,hs,dep,lt,rk,fa;set<int> son;}v[maxn];
void build(int x){
v[x].size=1;
if(!v[x].son.size()) return;
int mx=0;
for(auto it=v[x].son.begin();it!=v[x].son.end();++it){
v[*it].son.erase(x),v[*it].dep=v[x].dep+1,v[*it].fa=x;
build(*it),v[x].size+=v[*it].size;
if(v[*it].size>v[mx].size) mx=*it;
}
v[x].hs=mx,v[x].son.erase(mx);
}
void build1(int x){
if(!v[x].lt) v[x].lt=x;
v[x].rk=++top,a[top]=v[x].data;
if(v[x].hs) v[v[x].hs].lt=v[x].lt,build1(v[x].hs);
for(auto it=v[x].son.begin();it!=v[x].son.end();++it) build1(*it);
}
void add(int a,int b,int x){
while(v[a].lt!=v[b].lt){
if(v[v[a].lt].dep<v[v[b].lt].dep) swap(a,b);
t.change(1,v[a].rk,v[v[a].lt].rk,x),a=v[v[a].lt].fa;
}
if(v[a].rk>v[b].rk) swap(a,b);
t.change(1,v[a].rk,v[b].rk,x);
}
int sum(int a,int b){
int ans=0;
while(v[a].lt!=v[b].lt){
if(v[v[a].lt].dep<v[v[b].lt].dep) swap(a,b);
(ans+=t.sum(1,v[a].rk,v[v[a].lt].rk))%mod,a=v[v[a].lt].fa;
}
if(v[a].rk>v[b].rk) swap(a,b);
return (ans+=t.sum(1,v[a].rk,v[b].rk))%mod;
}
void addtree(int x,int a){t.change(1,v[x].rk,v[x].rk+v[x].size-1,a);}
int sumtree(int x){return t.sum(1,v[x].rk,v[x].rk+v[x].size-1);}
void dfs(int x){
if(v[x].hs) dfs(v[x].hs);
for(auto it=v[x].son.begin();it!=v[x].son.end();++it) dfs(*it);
}
signed main(){
for(int i=1;i<=n;++i) v[i].data=read();
for(int i=1;i<n;++i){
int a=read(),b=read();
v[a].son.insert(b),v[b].son.insert(a);
}
build(root);
build1(root);
t.init(1,1,n,a);
while(m--) switch(read()){
case(1):{
int x=read(),y=read(),z=read()%mod;
add(x,y,z);
break;
}
case(2):{
int x=read(),y=read();
write(sum(x,y)),puts("");
break;
}
case(3):{
int x=read(),y=read()%mod;
addtree(x,y);
break;
}
case(4):{
int x=read();
write(sumtree(x)),puts("");
break;
}
}
return 0;
}
by _sunkuangzheng_ @ 2023-09-12 23:30:32
@stars_czy
t.change(1,v[a].rk,v[v[a].lt].rk,x)
改成 t.change(1,v[v[a].lt].rk,v[a].rk,x)
,查询函数同理。改完以上两点即可 AC,如果有帮助给个关注谢谢喵 /kel
by STARSczy @ 2023-09-13 14:34:59
@sunkuangzheng 谢谢,已关注,已AC