这是之前的一份AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=1e5+5;
ll n,m,r,p,op,kas,cnt;
ll w[N],wt[N],head[N],fa[N],dep[N],id[N],siz[N],son[N],top[N];
struct edge
{
ll next,to;
}e[N<<1];
struct tree
{
ll l,r,val,laz_tag;
}t[N<<2];
void add(ll u,ll v)
{
e[++cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
}
void push_up(ll x)
{
t[x].val=(t[x<<1].val+t[x<<1|1].val)%p;
}
void push_down(ll x)
{
if(!t[x].laz_tag) return;
t[x<<1].laz_tag+=t[x].laz_tag;
t[x<<1|1].laz_tag+=t[x].laz_tag;
t[x<<1].val+=(t[x<<1].r-t[x<<1].l+1)*t[x].laz_tag;
t[x<<1].val%=p;
t[x<<1|1].val+=(t[x<<1|1].r-t[x<<1|1].l+1)*t[x].laz_tag;
t[x<<1|1].val%=p;
t[x].laz_tag=0;
}
void build(ll l,ll r,ll x)
{
t[x].l=l;
t[x].r=r;
if(l==r)
{
t[x].val=wt[l]%p;
return;
}
int mid=l+r>>1;
build(l,mid,x<<1);
build(mid+1,r,x<<1|1);
push_up(x);
}
inline ll query(ll nl,ll nr,ll l,ll r,ll x)
{
ll ans=0;
if(nl<=l&&r<=nr)
{
return t[x].val;
}
push_down(x);
int mid=l+r>>1;
if(nl<=mid) ans+=query(nl,nr,l,mid,x<<1);
if(nr>mid) ans+=query(nl,nr,mid+1,r,x<<1|1);
return ans;
}
void update(ll nl,ll nr,ll k,ll l,ll r,ll x)
{
if(nl<=l&&r<=nr)
{
t[x].val+=(r-l+1)*k;
t[x].laz_tag+=k;
return;
}
push_down(x);
ll mid=l+r>>1;
if(nl<=mid) update(nl,nr,k,l,mid,x<<1);
if(nr>mid) update(nl,nr,k,mid+1,r,x<<1|1);
push_up(x);
}
void dfs1(ll u,ll fath)
{
dep[u]=dep[fath]+1;
fa[u]=fath;
siz[u]=1;
ll maxson=-1;
for(ll i=head[u];i;i=e[i].next)
{
ll v=e[i].to;
if(v==fath) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>maxson)
{
maxson=siz[v];
son[u]=v;
}
}
}
void dfs2(ll u,ll fst)
{
id[u]=++kas;
top[u]=fst;
wt[kas]=w[u];
if(!son[u]) return;
dfs2(son[u],fst);
for(ll i=head[u];i;i=e[i].next)
{
ll v=e[i].to;
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
void trlist_update(ll u,ll v,ll w)
{
w%=p;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
update(id[top[u]],id[u],w,1,n,1);
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
update(id[u],id[v],w,1,n,1);
}
void son_update(ll root,ll w)
{
update(id[root],id[root]+siz[root]-1,w,1,n,1);
}
inline ll trlist_query(ll u,ll v)
{
ll ans=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans+=query(id[top[u]],id[u],1,n,1);
ans%=p;
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
ans+=query(id[u],id[v],1,n,1);
ans%=p;
return ans;
}
inline ll son_query(ll root)
{
return query(id[root],id[root]+siz[root]-1,1,n,1)%p;
}
int main()
{
scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
for(ll i=1;i<=n;i++)
scanf("%d",&w[i]);
for(ll i=1,u,v;i<n;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs1(r,0);
dfs2(r,r);
build(1,n,1);
for(ll i=1;i<=m;i++)
{
scanf("%lld",&op);
if(op==1)
{
ll u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
trlist_update(u,v,w);
}
if(op==2)
{
ll u,v;
scanf("%lld%lld",&u,&v);
printf("%lld\n",trlist_query(u,v));
}
if(op==3)
{
ll u,w;
scanf("%lld%lld",&u,&w);
son_update(u,w);
}
if(op==4)
{
ll u;
scanf("%lld",&u);
printf("%lld\n",son_query(u));
}
}
return 0;
}
今天又写了一份一直re感觉和上面的没有区别了
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,m,r,p,op,idx,cnt;
int head[N],dep[N],top[N],son[N],siz[N],fa[N],w[N],a[N],id[N];
struct edge
{
int to,next;
}e[N<<1];
struct segment_tree
{
int l,r,val,laz_tag;
}t[N<<2];
inline void push_up(int x)
{
t[x].val=(t[x<<1].val+t[x<<1|1].val)%p;
}
inline void push_down(int x)
{
if(!t[x].laz_tag) return;
t[x<<1].laz_tag+=t[x].laz_tag;
t[x<<1|1].laz_tag+=t[x].laz_tag;
t[x<<1].val+=(t[x<<1].r-t[x<<1].l+1)*t[x].laz_tag;
t[x<<1].val%=p;
t[x<<1|1].val+=(t[x<<1|1].r-t[x<<1|1].l+1)*t[x].laz_tag;
t[x<<1|1].val%=p;
t[x].laz_tag=0;
}
inline void build(int l,int r,int x)
{
t[x].l=l;
t[x].r=r;
if(l==r)
{
t[x].val=a[l]%p;
return;
}
int mid=l+r>>1;
build(l,mid,x<<1);
build(mid+1,r,x<<1|1);
push_up(x);
}
inline void update(int nl,int nr,int k,int l,int r,int x)
{
if(nl<=l&&r<=nr)
{
t[x].val+=(r-l+1)*k;
t[x].laz_tag+=k;
return;
}
push_down(x);
int mid=l+r>>1;
if(nl<=mid) update(nl,nr,k,l,mid,x<<1);
if(nr>mid) update(nl,nr,k,mid+1,r,x<<1|1);
push_up(x);
}
inline int query(int nl,int nr,int l,int r,int x)
{
if(nl<=l&&r<=nr)
{
return t[x].val;
}
push_down(x);
int mid=l+r>>1,res=0;
if(nl<=mid) res+=query(nl,nr,l,mid,x<<1);
if(nr>mid) res+=query(nl,nr,mid+1,r,x<<1|1);
return res;
}
inline void add_edge(int u,int v)
{
e[++cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
}
inline void dfs1(int u,int fath)
{
dep[u]=dep[fath]+1;
fa[u]=fath;
siz[u]=1;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v==fath) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])
son[u]=v;
}
}
inline void dfs2(int u,int fst)
{
id[u]=++idx;
a[idx]=w[u];
top[u]=fst;
if(!son[u]) return;
dfs2(fst,son[u]);
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
inline void trlist_update(int u,int v,int w)
{
w%=p;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
update(id[top[u]],id[u],w,1,n,1);
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
update(id[u],id[v],w,1,n,1);
}
inline int trlist_query(int u,int v)
{
int res=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res+=query(id[top[u]],id[u],1,n,1);
res%=p;
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
res+=query(id[u],id[v],1,n,1);
res%=p;
return res;
}
inline void son_update(int u,int w)
{
update(id[u],id[u]+siz[u]-1,w,1,n,1);
}
inline int son_query(int u)
{
return query(id[u],id[u]+siz[u]-1,1,n,1)%p;
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(NULL);
std::cout.tie(NULL);
cin>>n>>m>>r>>p;
for(int i=1;i<=n;i++)
cin>>w[i];
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
add_edge(u,v);
add_edge(v,u);
}
dfs1(r,0);
dfs2(r,r);
build(1,n,1);
while(m--)
{
cin>>op;
if(op==1)
{
int u,v,w;
cin>>u>>v>>w;
trlist_update(u,v,w);
}
if(op==2)
{
int u,v;
cin>>u>>v;
cout<<trlist_query(u,v)<<'\n';
}
if(op==3)
{
int u,w;
cin>>u>>w;
son_update(u,w);
}
if(op==4)
{
int u;
cin>>u;
cout<<son_query(u)<<'\n';
}
}
return 0;
}