社区讨论
萌新刚学OI,树链剖分莫名写炸求救
P3384【模板】重链剖分 / 树链剖分参与者 4已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @mi86bc4r
- 此快照首次捕获于
- 2025/11/21 09:20 4 个月前
- 此快照最后确认于
- 2025/11/21 09:20 4 个月前
RT,不知为何MLE
CPP#include <bits/stdc++.h>
using namespace std;
const int N=100005;
#define ll long long
int dep[N],siz[N],fa[N],z[N],to[N<<1],beg[N<<1],nxt[N<<1],top[N<<2],bian,son[N<<1],id[N<<1],tot,n,m,r,mod;
struct Tree{
ll ans[N<<2],tag[N<<2],a[N];
inline ll lson(ll p){return p<<1;}
inline ll rson(ll p){return (p<<1)|1;}
inline void push_up(ll p){ans[p]=(ans[lson(p)]+ans[rson(p)])%mod;}
inline void build(ll p,ll l,ll r){
if (l==r){ans[p]=a[l];return ;}
ll mid=(l+r)>>1;
build(lson(p),l,mid);
build(rson(p),mid+1,r);
push_up(p);
tag[p]=0;
}
inline void lazy_tag(ll p,ll l,ll r,ll k){ans[p]=(ans[p]+(r-l+1)*k)%mod,tag[p]=(tag[p]+k)%mod;}
inline void push_down(ll p,ll l,ll r){
ll mid=(l+r)>>1;
lazy_tag(lson(p),l,mid,tag[p]);
lazy_tag(rson(p),mid+1,r,tag[p]);
tag[p]=0;
}
inline void change(ll p,ll nl,ll nr,ll l,ll r,ll k){//nl,nr->changing l,changing r;l,r->visiting l,visiting r
if (nl<=l&&nr>=r){ans[p]=(ans[p]+(r-l+1)*k)%mod,tag[p]=(tag[p]+k)%mod;return ;}
ll mid=(l+r)>>1;
push_down(p,l,r);
if (nl<=mid)change(lson(p),nl,nr,l,mid,k);
if (nr>mid)change(rson(p),nl,nr,mid+1,r,k);
push_up(p);
}
inline ll ask(ll p,ll nl,ll nr,ll l,ll r){
if (nl<=l&&nr>=r)return ans[p];
ll mid=(l+r)>>1,res=0;
push_down(p,l,r);
if (nl<=mid)res=(res+ask(lson(p),nl,nr,l,mid))%mod;
if (nr>mid)res=(ask(rson(p),nl,nr,mid+1,r))%mod;
return res;
}
}tree;
inline void add(int u,int v){
to[++bian]=v;
nxt[bian]=beg[u];
beg[u]=bian;
}
inline void dfs1(int x){
siz[x]=1;
for (int i=beg[x];i;i=nxt[i]){
if (to[i]==fa[x])continue;
fa[to[i]]=x;
dep[to[i]]=dep[x]+1;
dfs1(to[i]);
siz[x]+=siz[to[i]];
if (siz[to[i]]>siz[son[x]])son[x]=to[i];
}
}
inline void dfs2(int x,int y){
top[x]=y;id[x]=++tot;
if (son[x])dfs2(son[x],y);
for (int i=beg[x];i;i=nxt[i]){
if (to[i]==fa[i]||to[i]==son[i])continue;
dfs2(to[i],to[i]);
}
}
int query(int x,int y){
int ans=0;
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]])swap(x,y);
ans=(ans+tree.ask(r,id[top[x]],id[x],1,n))%mod;
x=fa[top[x]];
}
if (dep[x]<dep[y])swap(x,y);
ans=(ans+tree.ask(r,id[y],id[x],1,n));
return ans;
}
void chge(int x,int y,int k){
k%=mod;
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]])swap(x,y);
tree.change(r,id[top[x]],id[x],1,n,k);
x=fa[top[x]];
}
if (dep[x]<dep[y])swap(x,y);
tree.change(r,id[y],id[x],1,n,k);
}
int main(){
scanf ("%lld%lld%lld%lld",&n,&m,&r,&mod);fa[r]=0,dep[r]=1;
for (int i=1;i<=n;i++)scanf ("%lld",&tree.a[i]);
for (int i=1;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
add(a,b),add(b,a);
}
dfs1(r);
dfs2(r,r);
tree.build(1,1,n);
while(m--){
int flag,x,y,k;
scanf ("%d",&flag);
switch (flag){
case 1:scanf ("%d%d%d",&x,&y,&k);chge(x,y,k);break;
case 2:scanf ("%d%d",&x,&y);printf("%lld\n",query(x,y));break;
case 3:scanf ("%d%d",&x,&k);tree.change(1,id[x],id[x]+siz[x]-1,1,n,k);break;
case 4:scanf ("%d",&x);printf("%lld\n",tree.ask(1,id[x],id[x]+siz[x]-1,1,n));
}
}
}
回复
共 8 条回复,欢迎继续交流。
正在加载回复...