社区讨论
本人奈珑,树剖模板小样例过不去输出 17 11 求条
P3384【模板】重链剖分 / 树链剖分参与者 7已保存回复 11
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 10 条
- 当前快照
- 1 份
- 快照标识符
- @mi8nd0ra
- 此快照首次捕获于
- 2025/11/21 17:17 3 个月前
- 此快照最后确认于
- 2025/11/21 19:00 3 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,q,root,mod,opt,x,y,z,a[100005];
vector<int> e[100005];
int dep[100005],siz[100005],hvy[100005],fa[100005];
int top[100005],id[100005],cnt;
int t[100005];
#define lowbit(x) x&(-x)
void add(int x,int y){
while(x<=n){
t[x]=(t[x]+y)%mod;
x+=lowbit(x);
}
return;
}
int query(int x){
int res=0;
while(x){
res=(res+t[x])%mod;
x-=lowbit(x);
}
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(id[top[x]],z);add(id[x]+1,-z);
x=fa[top[x]];
}
if(dep[x]<dep[y])
swap(x,y);
add(id[y],z);add(id[x]+1,-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(id[x])-query(id[top[x]]-1)+mod)%mod;
x=fa[top[x]];
}
if(dep[x]<dep[y])
swap(x,y);
res=(res+query(id[x])-query(id[y]-1)+mod)%mod;
return res;
}
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]>mx) mx=siz[v],hvy[u]=v;
}
++siz[u];
return;
}
void dfs2(int u,int head){
top[u]=head;id[u]=++cnt;
// printf("%d %d\n",u,id[u]);
add(id[u],a[u]);add(id[u]+1,-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);
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(id[x],y);
add(id[x]+siz[x],-y);
}else{
cin>>x;
cout<<(query(id[x]+siz[x]-1)-query(id[x]-1)+mod)%mod<<endl;
}
}
return 0;
}
回复
共 11 条回复,欢迎继续交流。
正在加载回复...