社区讨论
求调
P3384【模板】重链剖分 / 树链剖分参与者 2已保存回复 6
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @mhj1yir2
- 此快照首次捕获于
- 2025/11/03 19:24 4 个月前
- 此快照最后确认于
- 2025/11/03 19:24 4 个月前
CPP
#include<bits/stdc++.h>
#define lx x<<1
#define rx (x<<1)+1
using namespace std;
const int N=1e5+10,M=2e5+10;
#define int long long
int h[N],nx[M],to[M];
int vl[N];
int dfn[N],rhk[N];
int size[N],top[N];
int son[N],deep[N];
int f[N];
int n,k,root,mod,idx=1,tnum;
int tree[4*N];
int lz[4*N],l[4*N],r[4*N];
void egde_add(int u,int v)
{
nx[idx]=h[u];
to[idx]=v;
h[u]=idx++;
}
void dfs1(int u,int fa)
{
deep[u]=deep[fa]+1;
size[u]=1;
int mx=0;
for(int i=h[u];i;i=nx[i])
{
int v=to[i];
if(fa==v) continue;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>mx)
{
mx=size[v];
son[u]=v;
}
}
}
void dfs2(int u,int fa,int topf)
{
f[u]=fa;
top[u]=topf;
dfn[u]=++tnum;
rhk[dfn[u]]=u;
if(son[u]) dfs2(son[u],u,topf);
for(int i=h[u];i;i=nx[i])
{
int v=to[i];
if(fa==v) continue;
if(v==son[u]) continue;
dfs2(v,u,v);
}
// cout<<son[u]<<" "<<u<<endl;
}
void push_up(int x)
{
tree[x]=tree[lx]+tree[rx];
}
void push_down(int x)
{
lz[lx]+=lz[x];
lz[rx]+=lz[x];
tree[lx]+=lz[lx]*(r[lx]-l[lx]+1);
tree[rx]+=lz[rx]*(r[rx]-l[rx]+1);
lz[x]=0;
}
void build(int tl,int tr,int x)
{
l[x]=tl,r[x]=tr;
if(tl==tr)
{
// cout<<x<<" ";
tree[x]=vl[rhk[tl]];
return;
}
int mid=(tl+tr)>>1;
build(tl,mid,lx);
build(mid+1,tr,rx);
push_up(x);
}
void add(int dl,int dr,int x,int num)
{
if(dl<=l[x] && dr>=r[x])
{
lz[x]=num;
tree[x]+=num*(r[x]-l[x]+1);
return;
}
push_down(x);
int mid=(l[x]+r[x])>>1;
if(dl<=mid) add(dl,dr,lx,num);
if(dr>mid) add(dl,dr,rx,num);
push_up(x);
}
int query(int dl,int dr,int x)
{
if(dl<=l[x] && dr>=r[x])
{
return tree[x];
}
push_down(x);
int ans=0;
int mid=(l[x]+r[x])>>1;
if(dl<=mid) ans+=query(dl,dr,lx);
if(dr>mid) ans+=query(dl,dr,rx);
return ans;
}
void change(int x,int y,int z)
{
// cout<<query(dfn[5],dfn[5],1);
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
add(dfn[top[x]],dfn[x],1,z);
x=f[top[x]];
}
cout<<query(dfn[5],dfn[5],1)<<endl;
if(x>y) add(dfn[y],dfn[x],1,z);
else add(dfn[x],dfn[y],1,z);
}
int ask(int x,int y)
{
int res=0;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
res+=query(dfn[top[x]],dfn[x],1);
// cout<<x<<" "<<top[x]<<endl;
x=f[top[x]];
}
// cout<<res<<" ";
// cout<<x<<" "<<y<<" ";
if(x>y) res+=query(dfn[y],dfn[x],1);
else res+=query(dfn[x],dfn[y],1);
return res;
}
void solve(int t)
{
int x,y,z;
if(t==1)
{
cin>>x>>y>>z;
change(x,y,z);
}
if(t==2)
{
cin>>x>>y;
cout<<ask(x,y)<<"\n";
}
if(t==3)
{
cin>>x>>z;
add(dfn[x],dfn[x]+size[x]-1,1,z);
}
if(t==4)
{
cin>>x;
// cout<<query(dfn[x],dfn[x]+size[x]-1,1)<<"\n";
}
}
signed main(){
cin>>n>>k>>root>>mod;
for(int i=1;i<=n;i++) cin>>vl[i];
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
egde_add(u,v);
egde_add(v,u);
}
dfs1(root,root);
dfs2(root,root,root);
build(1,tnum,1);
int t;
for(int i=1;i<=k;i++) cin>>t,solve(t);
}
回复
共 6 条回复,欢迎继续交流。
正在加载回复...