RT,在经过整个下午的调试之后,我已经快要崩溃了。
我对着神鱼的代码看了一遍又一遍,方法学了一遍又一遍,差不多都能背诵全文了,还是过不了,只有十分,555.
哪位好心人愿意帮忙看一下吗?谢谢。
#include<cstdio>
#include<iostream>
#define maxn1 100005
#define maxn2 200005
#define ll long long
using namespace std;
ll n,m,q,s,muxii,cnt=0;
ll sum1[maxn1],sum2[maxn1];
ll now[maxn1],before[maxn2],u[maxn2],v[maxn2],son[maxn1],depth[maxn1],fa[maxn1],size[maxn1],id[maxn1],top[maxn1],w[maxn1];
ll lowbit(ll x){
return x&(-x);
}
void update(ll l,ll r,ll num){
ll ad1=(l-1)*num%muxii;
ll ad2=r*num%muxii;
for(int t=l;t<=n;t+=lowbit(t)){
sum1[t]+=num;
sum1[t]%=muxii;
sum2[t]+=ad1;
sum2[t]%=muxii;
}
for(int t=r+1;t<=n;t+=lowbit(t)){
sum1[t]-=num;
sum1[t]%=muxii;
sum2[t]-=ad2;
sum2[t]%=muxii;
}
return;
}
ll querypoint(ll i){
ll ans=0;
for(int t=i;t>0;t-=lowbit(t)){
ans+=sum1[t]*i-sum2[t];
ans%=muxii;
}
return ans;
}
ll query(ll l,ll r){
return querypoint(r)-querypoint(l-1);
}
void dfs1(ll x,ll f){
fa[x]=f;
size[x]=1;
depth[x]=depth[f]+1;
ll maxn=0;
for(ll i=now[x];i!=-1;i=before[i]){
if(v[i]==f)
continue;
dfs1(v[i],x);
if(size[v[i]]>maxn){
maxn=size[v[i]];
son[x]=v[i];
}
size[x]+=size[v[i]];
}
return;
}
void dfs2(ll x,ll anc){
top[x]=anc;
id[x]=++cnt;
if(w[x]!=0)
update(id[x],id[x],w[x]);
if(son[x]==0)
return;
dfs2(son[x],anc);
for(ll i=now[x];i!=-1;i=before[i]){
if(v[i]==fa[x]||v[i]==son[x])
continue;
dfs2(v[i],v[i]);
}
return;
}
void updatepath(ll x,ll y,ll k){
k%=muxii;
while(top[x]!=top[y]){
if(depth[top[x]]<depth[top[y]])
swap(x,y);
update(id[top[x]],id[x],k);
x=fa[top[x]];
}
if(depth[x]>depth[y])
swap(x,y);
update(id[x],id[y],k);
return;
}
ll querypath(ll x,ll y){
ll ans=0;
while(top[x]!=top[y]){
if(depth[top[x]]<depth[top[y]])
swap(x,y);
ans+=query(id[top[x]],id[x]);
ans=ans%muxii;
x=fa[top[x]];
}
if(depth[x]>depth[y])
swap(x,y);
ans+=query(id[x],id[y]);
ans=ans%muxii;
return ans;
}
void updateson(ll x,ll k){
k%=muxii;
update(id[x],id[x]+size[x]-1,k);
return;
}
ll queryson(ll x){
return query(id[x],id[x]+size[x]-1);
}
ll t,x,y,z;
int main(){
scanf("%lld%lld%lld%lld",&n,&q,&s,&muxii);
m=n-1;
for(ll i=1;i<=n;i++){
scanf("%lld",&w[i]);
now[i]=-1;
son[i]=-1;
depth[i]=0;
fa[i]=-1;
size[i]=0;
id[i]=0;
top[i]=-1;
}
for(ll i=1;i<=m;i++){
scanf("%lld%lld",&u[i],&v[i]);
before[i]=now[u[i]];
now[u[i]]=i;
}
for(ll i=m+1;i<=2*m;i++){
u[i]=v[i-m];
v[i]=u[i-m];
before[i]=now[u[i]];
now[u[i]]=i;
}
dfs1(s,0);
dfs2(s,s);
while(q--){
scanf("%lld",&t);
if(t==1){
scanf("%lld%lld%lld",&x,&y,&z);
updatepath(x,y,z);
}
if(t==2){
scanf("%lld%lld",&x,&y);
printf("%lld\n",querypath(x,y)%muxii);
}
if(t==3){
scanf("%lld%lld",&x,&z);
updateson(x,z);
}
if(t==4){
scanf("%lld",&x);
printf("%lld\n",queryson(x)%muxii);
}
}
return 0;
}