萌新刚学树剖1ms,样例不过求调

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

```cpp #include<bits/stdc++.h> #define int long long #define maxn 800005 using namespace std; int n,m,r,p,a[maxn],b[maxn],tree[maxn],lazy[maxn],head[maxn],to[maxn],nex[maxn],fa[maxn],top[maxn],num[maxn],son[maxn],dep[maxn],siz[maxn],sum,tot,res; void add(int x,int y) { tot++; to[tot]=y; nex[tot]=head[x]; head[x]=tot; return; } void dfs1(int u,int f,int d) { int maxx=0; dep[u]=d; fa[u]=f; siz[u]=1; for(int i=head[u];i;i=nex[i]) { int v=to[i]; if(v==f) continue; dfs1(v,u,d+1); siz[u]+=siz[v]; if(siz[v]>maxx) { son[u]=v; maxx=siz[v]; } } return; } void dfs2(int u,int topp) { num[u]=++sum; top[u]=topp; b[sum]=a[u]; if(!son[u]) return; dfs2(son[u],topp); for(int i=head[u];i;i=nex[i]) { int v=to[i]; if(v!=fa[u]&&v!=son[u]) { dfs2(v,v); } } return; } void pushup(int now) { tree[now]=tree[now*2]+tree[now*2+1]; tree[now]%=p; return; } void build(int now,int l,int r) { if(l==r) { tree[now]=a[l]; return; } int mid=l+r>>1; build(now*2,l,mid); build(now*2+1,mid+1,r); pushup(now); return; } void pushdown(int now,int len) { lazy[now*2]+=lazy[now]; lazy[now*2+1]+=lazy[now]; tree[now*2]+=lazy[now]*((len+1)/2); tree[now*2+1]+=lazy[now]*(len/2); tree[now*2]%=p; tree[now*2+1]%=p; lazy[now]=0; return; } void upd(int now,int l,int r,int ql,int qr,int k) { if(l>=ql&&r<=qr) { lazy[now]+=k; tree[now]+=k*(r-l+1); tree[now]%=p; return; } else { int mid=l+r>>1; if(lazy[now]) pushdown(now,r-l+1); if(ql<=mid) upd(now*2,l,mid,ql,qr,k); if(qr>mid) upd(now*2+1,mid+1,r,ql,qr,k); } return; } void upd1(int x,int y,int z) { z%=p; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); upd(1,1,n,num[top[x]],num[x],z); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); upd(1,1,n,num[x],num[y],z); return; } int qry(int now,int l,int r,int ql,int qr) { if(l>r||r<ql||l>qr) return 0; if(l>=ql&&r<=qr) return tree[now]%p; else { int mid=l+r>>1; if(lazy[now]) pushdown(now,r-l+1); return (qry(now*2,l,mid,ql,qr)+qry(now*2+1,mid+1,r,ql,qr))%p; } } int query1(int x,int y) { int ans=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans+=qry(1,1,n,num[top[x]],num[x]); ans%=p; x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); ans+=qry(1,1,n,num[x],num[y]); return ans%p; } signed main() { cin>>n>>m>>r>>p; for(int i=1;i<=n;i++) { cin>>a[i]; } for(int i=1;i<=n-1;i++) { int x,y; cin>>x>>y; add(x,y); add(y,x); } dfs1(r,0,1); dfs2(r,r); for(int i=1;i<=n;i++) a[i]=b[i]; build(1,1,n); while(m--) { int opt,x,y,z; cin>>opt; if(opt==1) { cin>>x>>y>>z; upd1(x,y,z); } if(opt==2) { cin>>x>>y; cout<<query1(x,y)<<endl; } if(opt==3) { cin>>x>>z; upd(1,1,n,num[x],num[x]+siz[x]-1,z); } if(opt==4) { cin>>x; cout<<qry(1,1,n,num[x],num[x]+siz[x]-1)<<endl; } } return 0; } ``` 最新情况:改成这样后10分了
by Eason2009 @ 2022-07-14 17:57:53


@[Eason2009](/user/286448) Update 没 Pushup 加了就 AC 了
by Sharing666 @ 2022-07-14 18:30:19


@[Sharing666](/user/394991) 感谢巨佬,终于AC了,两个关注已给
by Eason2009 @ 2022-07-14 18:33:06


不用谢 qwq
by Sharing666 @ 2022-07-14 18:45:55


|