社区讨论
树剖模板 28pts 求条,only AC #2#3#11
P3384【模板】重链剖分 / 树链剖分参与者 3已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @miceq412
- 此快照首次捕获于
- 2025/11/24 08:26 3 个月前
- 此快照最后确认于
- 2025/11/24 11:12 3 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,q,root,mod,opt,x,y,z,a[100005],val[100005];
vector<int> e[100005];
int dep[100005],siz[100005],hvy[100005],fa[100005];
int top[100005],id[100005],cnt;
int t[400005],b[400005];
void build(int l,int r,int p){
if(l==r){
t[p]=val[l]%mod;
return;
}
int mid=l+r>>1;
build(l,mid,p<<1);
build(mid+1,r,p<<1|1);
t[p]=(t[p<<1]+t[p<<1|1])%mod;
return;
}
void pushdown(int l,int r,int p){
if(!b[p]) return;
int mid=l+r>>1;
t[p<<1]=(t[p<<1]+(mid-l+1)*b[p]%mod)%mod;
t[p<<1|1]=(t[p<<1|1]+(r-mid)*b[p]%mod)%mod;
b[p<<1]=(b[p<<1]+b[p])%mod;
b[p<<1|1]=(b[p<<1|1]+b[p])%mod;
b[p]=0;
return;
}
void add(int l,int r,int p,int x,int y,int z){
if(x<=l&&r<=y){
t[p]=(t[p]+z*(r-l+1)%mod)%mod;
b[p]=(b[p]+z)%mod;
return;
}
pushdown(l,r,p);
int mid=l+r>>1;
if(x<=mid) add(l,mid,p<<1,x,y,z);
if(y>mid) add(mid+1,r,p<<1|1,x,y,z);
t[p]=(t[p<<1]+t[p<<1|1])%mod;
return;
}
int query(int l,int r,int p,int x,int y){
if(x<=l&&r<=y) return t[p];
pushdown(l,r,p);
int mid=l+r>>1,res=0;
if(x<=mid) res=(res+query(l,mid,p<<1,x,y))%mod;
if(y>mid) res=(res+query(mid+1,r,p<<1|1,x,y))%mod;
return res;
}
void addPath(int x,int y,int z){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])
swap(x,y);
add(1,n,1,id[top[x]],x,z);
x=fa[top[x]];
}
if(dep[x]<dep[y])
swap(x,y);
add(1,n,1,id[y],id[x],z);
return;
}
int queryPath(int x,int y){
int res=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])
swap(x,y);
res=(res+query(1,n,1,id[top[x]],id[x])+mod)%mod;
x=fa[top[x]];
}
if(dep[x]<dep[y])
swap(x,y);
res=(res+query(1,n,1,id[y],id[x])+mod)%mod;
return res%mod;
}
void dfs1(int u,int f){
fa[u]=f;dep[u]=dep[f]+1;int mx=0;
for(auto v:e[u]){
if(v==f) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[hvy[u]]) hvy[u]=v;
}
++siz[u];return;
}
void dfs2(int u,int head){
top[u]=head;id[u]=++cnt;val[cnt]=a[u];
if(!hvy[u]) return;
dfs2(hvy[u],head);
for(auto v:e[u]){
if(v==hvy[u]||v==fa[u]) continue;
dfs2(v,v);
}
return;
}
signed main(){
cin>>n>>q>>root>>mod;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1,u,v;i<n;i++){
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(root,0);
dfs2(root,root);
build(1,n,1);
while(q--){
cin>>opt;
if(opt==1){
cin>>x>>y>>z;
addPath(x,y,z);
}else if(opt==2){
cin>>x>>y;
cout<<queryPath(x,y)%mod<<endl;
}else if(opt==3){
cin>>x>>y;
add(1,n,1,id[x],id[x]+siz[x]-1,y);
}else{
cin>>x;
cout<<(query(1,n,1,id[x],id[x]+siz[x]-1)+mod)%mod<<endl;
}
}
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...