Binah_cyc @ 2024-01-18 21:49:41
rt,过不了样例求助
#include <bits/stdc++.h>
using namespace std;
//#define int long long
const int N=1e5+5;
int mod;
int n,m,r,sum[N];
int f[N],son[N],sze[N],deep[N],id[N],top[N],a[N],cnt;
int tot,head[N];
struct Node
{
int nxt,to;
} edge[N<<1];
struct SegementTree
{
int l,r;
int ans,add;
} t[N<<2];
void add(int x,int y)
{
edge[++tot]=(Node)
{
head[x],y
};
head[x]=tot;
}
void dfs1(int now,int fa,int dep)
{
deep[now]=dep;
f[now]=fa;
sze[now]=1;
int t=-1;
for(int i=head[now]; i; i=edge[i].nxt)
{
if(edge[i].to==fa) continue;
dfs1(edge[i].to,now,dep+1);
sze[now]+=sze[edge[i].to];
if(sze[edge[i].to]>t) t=sze[edge[i].to],son[now]=edge[i].to;
}
}
void dfs2(int now,int ffa)
{
id[now]=++cnt;
a[cnt]=sum[now];
top[cnt]=ffa;
if(!son[now]) return ;
dfs2(son[now],ffa);
for(int i=head[now]; i; i=edge[i].nxt)
{
if(edge[i].to==son[now]||edge[i].to==f[now]) continue;
dfs2(edge[i].to,edge[i].to);
}
}
void build(int l,int r,int p)
{
t[p].l=l;
t[p].r=r;
if(l==r)
{
t[p].ans=a[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,p*2);
build(mid+1,r,p*2+1);
t[p].ans=t[p*2].ans+t[p*2+1].ans;
return ;
}
void spread(int p)
{
if(t[p].add)
{
t[p*2].ans=(t[p*2].ans+(t[p*2].r-t[p*2].l+1)*t[p].add)%mod;
t[p*2+1].ans=(t[p*2+1].ans+(t[p*2+1].r-t[p*2+1].l+1)*t[p].add)%mod;
t[p*2].add+=t[p].add;
t[p*2+1].add+=t[p].add;
t[p].add=0;
}
return ;
}
void change(int l,int r,int k,int p)
{
if(l<=t[p].l&&r>=t[p].r)
{
t[p].ans=(t[p].ans+(t[p].r-t[p].l+1)*k)%mod;
t[p].add+=k;
return ;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) change(l,r,k,p*2);
if(r>mid) change(l,r,k,p*2+1);
t[p].ans=t[p*2].ans+t[p*2+1].ans;
return ;
}
int ask(int l,int r,int p)
{
if(l<=t[p].l&&t[p].r<=r) return t[p].ans;
spread(p);
int sum=0,mid=(t[p].l+t[p].r)>>1;
if(l<=mid) sum+=ask(l,r,p*2);
if(r>mid) sum+=ask(l,r,p*2+1);
return sum;
}
void changeroad(int x,int y,int num)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
change(id[top[x]],id[x],num,1);
x=f[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);
change(id[x],id[y],num,1);
}
int askroad(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
ans=(ans+ask(id[top[x]],id[x],1))%mod;
x=f[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);
return (ans+ask(id[x],id[y],1))%mod;
}
void changetree(int x,int num)
{
change(id[x],id[x]+sze[x]-1,num,1);
return ;
}
int asktree(int x)
{
return ask(id[x],id[x]+sze[x]-1,1);
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>r>>mod;
int x,y;
for(int i=1; i<=n; i++) cin>>sum[i];
for(int i=1; i<n; i++)
{
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs1(r,0,1);
dfs2(r,r);
build(1,n,1);
while(m--)
{
int op,x,y,z;
cin>>op;
if(op==1)
{
cin>>x>>y>>z;
changeroad(x,y,z%mod);
}
else if(op==2)
{
cin>>x>>y;
cout<<askroad(x,y)<<endl;
}
else if(op==3)
{
cin>>x>>z;
changetree(x,z);
}
else if(op==4)
{
cin>>x;
cout<<asktree(x)<<endl;
}
// cout<<askroad(1,1)<<' '<<askroad(3,3)<<' '<<askroad(4,4)<<' '<<askroad(5,5)<<" "<<endl;
}
// for(int i=1;i<=n;i++) cout<<i<<' '<<"deep:"<<deep[id[i]]<<' '<<"f:"<<f[id[i]]<<' '<<"id:"<<id[i]<<' '<<"son:"<<son[id[i]]<<' '<<"sum:"<<sum[id[i]]<<' '<<"sze:"<<sze[id[i]]<<' '<<"top:"<<top[id[i]]<<'\n';
return 0;
}
by sunkuangzheng @ 2024-01-18 21:58:24
@Binah_cyc
by Binah_cyc @ 2024-01-18 22:04:26
@sunkuangzheng 谢谢,已关!