社区讨论
树剖求助,37pts
P3384【模板】重链剖分 / 树链剖分参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @lt3ripfi
- 此快照首次捕获于
- 2024/02/27 10:42 2 年前
- 此快照最后确认于
- 2024/02/27 10:59 2 年前
树剖求助,37pts```cpp
#include<bits/stdc++.h>
#define qwe(i,a,b) for(int i=a;i<=b;i++)
#define itn int
#define asn ans
#define reisze resize
#define ls ((u)<<1)
#define rs ((u)<<1|1)
#define LL long long
using namespace std;
constexpr int N=6e5+5;
constexpr LL inf=1e12;
vector G[N];
LL n,m,q,p;
vector val;
LL dfn[N],fa[N],son[N],top[N],dep[N],siz[N],rm[N];
LL tag[N],sum[N];
int cnt;
void dfs1(int x,int f){
fa[x]=f;
dep[x]=dep[f]+1;
siz[x]=1;
LL maxx=0;
for(int ne:G[x]){
if(ne==f)continue;
dfs1(ne,x);
if(siz[ne]>maxx){
maxx=siz[ne];
son[x]=ne;
}
siz[x]+=siz[ne];
}
}
void dfs2(int x,int tp){
dfn[x]=++cnt;
top[x]=tp;
if(son[x])dfs2(son[x],tp);
for(int ne:G[x]){
if(ne==son[x]||ne==fa[x])continue;
dfs2(ne,ne);
}
rm[x]=cnt;
}
int LCA(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
return dep[x]>dep[y]?y:x;
}
void cov(int u,int l,int r,LL v){
tag[u]+=v;
sum[u]+=((r-l+1)%p)*v%p;
sum[u]%=p,tag[u]%=p;
}
void down(int u,int l,int r){
if(tag[u]){
int mid=(l+r)>>1;
cov(ls,l,mid,tag[u]);
cov(rs,mid+1,r,tag[u]);
tag[u]=0;
}
}
void up(int u){
sum[u]=(sum[ls]+sum[rs])%p;
}
void change(int u,int l,int r,int L,int R,LL v){
if(L<=l&&R>=r){
cov(u,l,r,v);
return;
}
down(u,l,r);
int mid=(l+r)>>1;
if(L<=mid)change(ls,l,mid,L,R,v);
if(R>mid)change(rs,mid+1,r,L,R,v);
up(u);
}
LL query(int u,int l,int r,int L,int R){
if(L<=l&&R>=r)return sum[u];
down(u,l,r);
int mid=(l+r)>>1;
LL res=0;
if(L<=mid)res+= query(ls,l,mid,L,R),res%=p;
if(R>mid)res+= query(rs,mid+1,r,L,R),res%=p;
return res;
}
void add1(itn x,int y,LL v){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
change(1,1,n,dfn[top[x]],dfn[x],v),x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
change(1,1,n,dfn[x],dfn[y],v);
}
LL ask1(int x,int y){
LL res=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
res+= query(1,1,n,dfn[top[x]],dfn[top[x]]),res%=p,x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
res+= query(1,1,n,dfn[x],dfn[y]);
res%=p;
return res;
}
void add2(int x,LL v){
change(1,1,n,dfn[x],rm[x],v);
}
LL ask2(int x){
return query(1,1,n,dfn[x],rm[x]);
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin>>n>>m>>q>>p;
val.resize(n+1);
for(int i=1;i<=n;i++)cin>>val[i];
for(int i=0;i<n-1;i++){
int u,v;
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
dfs1(q,0);
dfs2(q,q);
for(int i=1;i<=n;i++)add1(i,i,val[i]%p);
for(int i=0;i<m;i++){
int op;
cin>>op;
int x,y;
LL z;
if(op==1){
cin>>x>>y>>z;
z%=p;
add1(x,y,z);
}else if(op==2){
cin>>x>>y;
cout<<ask1(x,y)%p<<'\n';
}else if(op==3){
cin>>x>>z;
z%=p;
add2(x,z);
}else{
cin>>x;
cout<<ask2(x)%p<<'\n';
}
}
}
CPP回复
共 1 条回复,欢迎继续交流。
正在加载回复...