调吐了,30pts求助/kel/kel/kel

P3384 【模板】重链剖分/树链剖分

```cpp #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; typedef long long ll; inline int read() { int s=0,w=1; char ch=getchar(); while(ch<'0' or ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0' and ch<='9')s=s*10+(ch-'0'),ch=getchar(); return s*w; } inline ll read_ll() { ll s=0,w=1; char ch=getchar(); while(ch<'0' or ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0' and ch<='9')s=s*10+(ch-'0'),ch=getchar(); return s*w; } const int MAXN(1e5+10); int n,m,rt; ll mod,a[MAXN],b[MAXN]; struct E{int to,nxt;}; E edge[MAXN<<1]; int head[MAXN],tot,cnt; int idx[MAXN],rk[MAXN],top[MAXN],par[MAXN],son[MAXN],dep[MAXN],siz[MAXN]; inline void Swap(int&x,int&y){x^=y;y^=x;x^=y;} //idx[u] u在序列的位置 //rk[u] dfs序为 u 的节点编号 inline void add_edge(int u,int v) { edge[++tot].nxt=head[u]; head[u]=tot; edge[tot].to=v; return; } struct Segment { ll tree[MAXN*4],tag[MAXN*4]; inline int lc(int p){return p<<1;} inline int rc(int p){return p<<1|1;} inline void push_up(int u){tree[u]=(tree[lc(u)]+tree[rc(u)])%mod;return;} inline void lazy_tag(int u,int l,int r,ll k) { tag[u]=(tag[u]+k)%mod; tree[u]=(tree[u]+k*(r-l+1))%mod; return; } inline void push_down(int u,int l,int r) { int mid=(l+r)>>1; lazy_tag(lc(u),l,mid,tag[u]); lazy_tag(rc(u),mid+1,r,tag[u]); tag[u]=0; return; } inline void build(int u,int l,int r) { if(l==r) { tree[u]=a[rk[l]]; return; } int mid=(l+r)>>1; build(lc(u),l,mid); build(rc(u),mid+1,r); push_up(u); return; } inline void update(int u,int l,int r,int ln,int rn,ll k) { if(ln<=l&&r<=rn) { lazy_tag(u,l,r,k); return; } push_down(u,l,r); int mid=(l+r)>>1; if(ln<=mid) update(lc(u),l,mid,ln,rn,k); if(rn>mid) update(rc(u),mid+1,r,ln,rn,k); push_up(u); return; } inline ll query(int u,int l,int r,int ln,int rn) { ll res(0); if(ln<=l&&r<=rn) return tree[u]%mod; push_down(u,l,r); int mid=(l+r)>>1; if(ln<=mid) res=(res+query(lc(u),l,mid,ln,rn))%mod; if(rn>mid) res=(res+query(rc(u),mid+1,r,ln,rn))%mod; return res; } }; Segment Tree; inline void dfs1(int u,int fa,int depth) { siz[u]=1; dep[u]=depth; par[u]=fa; for(register int i=head[u];i;i=edge[i].nxt) { E e=edge[i]; if(e.to==fa) continue; dfs1(e.to,u,depth+1); siz[u]+=siz[e.to]; if(siz[e.to]>siz[son[u]]) son[u]=e.to; } return; } inline void dfs2(int u,int topf) { top[u]=topf; idx[u]=++cnt; rk[cnt]=u; if(!son[u]) return;//叶子节点没有重儿子 dfs2(son[u],topf); for(register int i=head[u];i;i=edge[i].nxt) { E e=edge[i]; if(e.to==par[u]||e.to==son[u]) continue; dfs2(e.to,e.to); } return; } inline ll sum(int x,int y) { int fx=top[x],fy=top[y]; ll res(0); while(fx!=fy) { if(dep[fx]>=dep[fy]) { res=(res+Tree.query(1,1,n,idx[fx],idx[x]))%mod; x=par[fx]; fx=top[x]; } else { res=(res+Tree.query(1,1,n,idx[fy],idx[y]))%mod; y=par[fy]; fy=top[y]; } } if(idx[x]>idx[y]) Swap(x,y); res=(res+Tree.query(1,1,n,idx[x],idx[y]))%mod; return res; } inline void modify(int x,int y,ll k) { int fx=top[x],fy=top[y]; while(fx!=fy) { if(dep[fx]>=dep[fy]) { Tree.update(1,1,n,idx[fx],idx[x],k); x=par[x]; fx=top[x]; } else { Tree.update(1,1,n,idx[fy],idx[y],k); y=par[y]; fy=top[y]; } } if(idx[x]>idx[y]) Swap(x,y); Tree.update(1,1,n,idx[x],idx[y],k); return; } inline void change(int u,ll k) { Tree.update(1,1,n,idx[u],idx[u]+siz[u]-1,k); return; } inline int qson(int u){return Tree.query(1,1,n,idx[u],idx[u]+siz[u]-1);} int main() { n=read(),m=read(),rt=read(),mod=read_ll(); for(register int i=1;i<=n;i++) a[i]=read_ll(); for(register int i=1;i<n;i++) { int u=read(),v=read(); add_edge(u,v); add_edge(v,u); } dfs1(rt,0,1); dfs2(rt,rt); Tree.build(1,1,n); while(m--) { int opt=read(); if(opt==1) { int x=read(),y=read(); ll z=read_ll()%mod; modify(x,y,z); } else if(opt==2) { int x=read(),y=read(); printf("%lld\n",sum(x,y)%mod); } else if(opt==3) { int u=read(); ll k=read_ll()%mod; change(u,k); } else { int u=read(); printf("%lld\n",qson(u)%mod); } } return 0; } ```
by UperFicial @ 2021-07-21 14:33:33


@[UperFicial](/user/360511) 这不是std吧(
by ByGones @ 2021-07-21 14:34:49


@[卞宇轩](/user/209848) 确实(
by UperFicial @ 2021-07-21 14:48:23


@[UperFicial](/user/360511) modify里面应该是 `x=par[fx]`, y 同理 实测能过了
by w23c3c3 @ 2021-07-21 15:28:11


@[UperFicial](/user/360511) 建议学习一下题解第一篇,特别简洁qwq,您这种写法感觉太冗杂了
by Durancer @ 2021-07-21 15:28:14


@[w23c3c3](/user/109942) 感谢
by UperFicial @ 2021-07-21 15:30:24


@[Chen_怡](/user/230804) ok
by UperFicial @ 2021-07-21 15:33:15


有钱人
by peterwuyihong @ 2021-07-21 15:34:30


立竿见影
by Evier @ 2021-07-21 19:32:33


|