W_Sibo @ 2024-08-21 14:16:12
#include <iostream>
using namespace std;
typedef long long ll;
const ll N=100005;
ll n,m,r,mod;
ll a[N];
ll siz[N],fa[N],dep[N],seg[N],rev[N],top[N],son[N];
ll hd[N],nt[2*N],v[2*N],cnt=1;
ll tr[N*4],mk[N*4];
inline void add(ll x,ll y){
v[++cnt]=y;
nt[cnt]=hd[x];
hd[x]=cnt;
}
inline void dfs1(ll u,ll f){
siz[u]=1;
fa[u]=f;
dep[u]=dep[f]+1;
for(ll i=hd[u];i;i=nt[i]){
ll y=v[i];
if(y!=f){
dfs1(y,u);
siz[u]+=siz[y];
if(siz[y]>siz[son[u]]){
son[u]=y;
}
}
}
}
inline void dfs2(ll u,ll f){
if(son[u]){
seg[son[u]]=++seg[0];
top[son[u]]=top[u];
rev[seg[0]]=son[u];
dfs2(son[u],u);
}
for(ll i=hd[u];i;i=nt[i]){
ll y=v[i];
if(!top[y]){
seg[y]=++seg[0];
rev[seg[0]]=y;
top[y]=y;
dfs2(y,u);
}
}
}
inline void build(ll l,ll r,ll p){
if(l==r){
tr[p]=a[rev[l]];
}else{
ll mid=(l+r)/2;
build(l,mid,p*2);
build(mid+1,r,p*2+1);
tr[p]=tr[p*2]+tr[p*2+1];
}
}
inline void push_down(ll p,ll len){
mk[p*2]+=mk[p];
mk[p*2+1]+=mk[p];
tr[p*2]+=mk[p]*(len-len/2);
tr[p*2+1]+=mk[p]*(len/2);
mk[p]=0;
}
inline void update(ll l,ll r,ll d,ll p,ll cl,ll cr){
if(cl>r||cr<l){
return;
}else if(cl>=l&&cr<=r){
tr[p]+=(cr-cl+1)*d;
if(cr>cl){
mk[p]+=d;
}
}else{
ll mid=(cl+cr)/2;
push_down(p,cr-cl+1);
update(l,r,d,p*2,cl,mid);
update(l,r,d,p*2+1,mid+1,cr);
tr[p]=tr[p*2]+tr[p*2+1];
}
}
inline ll query(ll l,ll r,ll p,ll cl,ll cr){
if(cl>r||cr<l){
return 0;
}else if(cl>=l&&cr<=r){
return tr[p];
}else{
ll mid=(cl+cr)/2;
push_down(p,cr-cl+1);
return (ll)(query(l,r,p*2,cl,mid)+query(l,r,p*2+1,mid+1,cr));
}
}
inline void op1(ll x,ll y,ll z){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
swap(x,y);
}
update(seg[top[x]],seg[x],z,1,1,n);
x=fa[top[x]];
}
if(dep[x]>dep[y]){
swap(x,y);
}
update(seg[x],seg[y],z,1,1,n);
}
inline ll op2(ll x,ll y){
ll ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
swap(x,y);
}
ans=(ans+query(seg[top[x]],seg[x],1,1,n));
x=fa[top[x]];
}
if(dep[x]>dep[y]){
swap(x,y);
}
ans=(ans+query(seg[x],seg[y],1,1,n));
return ans;
}
inline void op3(ll x,ll y){
update(seg[x],seg[x]+siz[x]-1,y,1,1,n);
}
inline ll op4(ll x){
return query(seg[x],seg[x]+siz[x]-1,1,1,n);
}
int main(){
std::ios::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
cin>>n>>m>>r>>mod;
for(ll i=1;i<=n;i++){
cin>>a[i];
}
for(ll i=1;i<n;i++){
ll x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs1(r,0);
seg[r]=++seg[0];
top[r]=r;
rev[r]=1;
dfs2(r,0);
build(1,n,1);
for(ll i=1;i<=m;i++){
ll k;
cin>>k;
if(k==1){
ll x,y,z;
cin>>x>>y>>z;
op1(x,y,z);
}else if(k==2){
ll x,y;
cin>>x>>y;
cout<<op2(x,y)%mod<<'\n';
}else if(k==3){
ll x,y;
cin>>x>>y;
op3(x,y);
}else{
ll x;
cin>>x;
cout<<op4(x)%mod<<'\n';
}
}
}
by W_Sibo @ 2024-08-21 14:27:03
input:
8 10 2 448348
458 718 447 857 633 264 238 944
1 2
2 3
3 4
6 2
1 5
5 7
8 6
3 7 611
4 6
3 1 267
3 2 111
1 6 3 153
3 7 673
4 8
2 6 1
4 7
3 4 228
正确output:
1208
1055
2346
1900
我的output:
1208
1055
1628
1900
by W_Sibo @ 2024-08-21 14:31:57
大概率是op2的问题
by W_Sibo @ 2024-08-21 15:23:04
已过,此贴结
by _zhengzachary @ 2024-08-24 09:25:12
又调了几个小时?罚了多少时?