社区讨论
37ptsWA求条
P3384【模板】重链剖分 / 树链剖分参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mjl3o7ax
- 此快照首次捕获于
- 2025/12/25 15:07 2 个月前
- 此快照最后确认于
- 2025/12/27 15:20 2 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll MOD;
ll n,m,r,a[N],b[N];
vector<ll> e[N];
struct segtree{
ll tr[4*N],l[4*N],r[4*N],laz[4*N];
void init(ll u,ll L,ll R){
l[u]=L,r[u]=R,laz[u]=0;
if(L==R){
tr[u]=a[L];
tr[u]%=MOD;
return ;
}
ll mid=(L+R)/2;
init(u*2,L,mid),init(u*2+1,mid+1,R);
tr[u]=tr[u*2]+tr[u*2+1];
tr[u]%=MOD;
}
void build(){init(1,1,n);}
void lazdown(ll u){
if(l[u]==r[u]||!laz[u])return ;
tr[u*2]+=laz[u]*(r[u*2]-l[u*2]+1),tr[u*2]%=MOD;
tr[u*2+1]+=laz[u]*(r[u*2+1]-l[u*2+1]+1),tr[u*2+1]%=MOD;
laz[u*2]+=laz[u],laz[u*2]%=MOD;
laz[u*2+1]+=laz[u],laz[u*2+1]%=MOD;
laz[u]=0;
}
void A(ll u,ll L,ll R,ll val){
lazdown(u);
if(l[u]>=L&&r[u]<=R){
tr[u]+=val*(r[u]-l[u]+1),tr[u]%=MOD;
laz[u]+=val,laz[u]%=MOD;
return ;
}
if(l[u]>R||r[u]<L)return ;
A(u*2,L,R,val),A(u*2+1,L,R,val);
tr[u]=tr[u*2]+tr[u*2+1],tr[u]%=MOD;
}
void add(ll L,ll R,ll val){A(1,L,R,val);}
ll Q(ll u,ll L,ll R){
lazdown(u);
if(l[u]>=L&&r[u]<=R)return tr[u];
if(l[u]>R||r[u]<L)return 0;
return (Q(u*2,L,R)+Q(u*2+1,L,R))%MOD;
}
ll query(ll L,ll R){return Q(1,L,R);}
}tr;
ll fa[N],dep[N],siz[N],son[N],id[N],top[N];
void dfs1(ll u,ll f,ll deep){
fa[u]=f,dep[u]=deep,siz[u]=1;
for(auto i:e[u]){
if(i==f)continue;
dfs1(i,u,deep+1);
siz[u]+=siz[i];
if(siz[son[u]]<siz[i])son[u]=i;
}
}
ll cnt=0;
void dfs2(ll u,ll topf){
cnt++;
top[u]=topf,id[u]=cnt;
a[cnt]=b[u];
if(son[u])dfs2(son[u],topf);
for(auto i:e[u])if(i!=fa[u]&&i!=son[u])dfs2(i,i);
}
void add(ll x,ll y,ll val){
while(top[x]!=top[y]){
if(dep[x]<dep[y])x^=y,y^=x,x^=y;
tr.add(id[top[x]],id[x],val);
x=fa[top[x]];
}
if(dep[x]<dep[y])x^=y,y^=x,x^=y;
tr.add(id[y],id[x],val);
}
ll query(ll x,ll y){
ll ans=0;
while(top[x]!=top[y]){
if(dep[x]<dep[y])x^=y,y^=x,x^=y;
ans+=tr.query(id[top[x]],id[x]),ans%=MOD;
x=fa[top[x]];
}
if(dep[x]<dep[y])x^=y,y^=x,x^=y;
ans+=tr.query(id[y],id[x]),ans%=MOD;
return ans;
}
int main(){
std::ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m>>r>>MOD;
for(int i=1;i<=n;i++)cin>>b[i];
for(int i=1;i<=n-1;i++){
ll u,v;
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(r,r,0);
dfs2(r,r);
tr.build();
for(int i=1;i<=m;i++){
ll c,x,y,z;
cin>>c;
if(c==1){
cin>>x>>y>>z;
add(x,y,z);
}
if(c==2){
cin>>x>>y;
cout<<query(x,y)<<"\n";
}
if(c==3){
cin>>x>>z;
tr.add(id[x],id[x]+siz[x]-1,z);
}
if(c==4){
cin>>x;
cout<<tr.query(id[x],id[x]+siz[x]-1)<<"\n";
}
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...