萌新刚学树剖 re...

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

```cpp if(size[to]>maxson){ maxson=size[u]; son[u]=to; } ``` 那里的maxson不该赋值为size[to]吗
by mzgwty @ 2019-08-03 09:11:17


您还应该再弄一个数组,存每个节点在线段树中的位置
by mzgwty @ 2019-08-03 09:16:00


@[Old_Wang](/space/show?uid=79075) 改完了开始wa ```cpp #include<cstdio> #include<iostream> #define rint register int using namespace std; const int N=500005; int u[N],v[N],first[N],next[N]; int dpt[N],fa[N],son[N],top[N],idx[N],size[N],val[N],pre[N]; int tot,cnt; int n,m,r,mod; int read(){ int f=1,x=0;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return f*x; } void add(int x,int y){ u[++tot]=x,v[tot]=y; next[tot]=first[x]; first[x]=tot; } void dfs1(int u,int pa,int depth){ fa[u]=pa; dpt[u]=depth; size[u]=1; int maxson=-1; for(rint i=first[u];i;i=next[i]){ int to=v[i]; if(to==pa) continue; dfs1(to,u,depth+1); size[u]+=size[to]; if(size[to]>maxson){ maxson=size[to]; son[u]=to; } } } void dfs2(int u,int tp){ idx[u]=++cnt; top[u]=tp; val[cnt]=pre[u]; if(son[u]) dfs2(son[u],tp); for(rint i=first[u];i;i=next[i]){ if(!idx[v[i]]&&v[i]!=fa[u]){ dfs2(v[i],v[i]); } } } struct SegmentTree{ int l,r,sum,lazy; #define ls p<<1 #define rs p<<1|1 }t[4*N]; void pushup(int p){ t[p].sum=(t[ls].sum+t[rs].sum)%mod;; } void pushdown(int p){ if(t[p].lazy){ t[ls].lazy=(t[ls].lazy+t[p].lazy)%mod; t[rs].lazy=(t[rs].lazy+t[p].lazy)%mod; t[p].lazy=0; t[ls].sum=(t[ls].sum+t[p].lazy*(t[ls].r-t[ls].l+1))%mod; t[rs].sum=(t[rs].sum+t[p].lazy*(t[rs].r-t[ls].l+1))%mod; } } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; if(l==r){t[p].sum=pre[l];return;} int mid=(l+r)/2; build(ls,l,mid); build(rs,mid+1,r); pushup(p); } void add(int p,int l,int r,int k){ if(t[p].l>=l&&t[p].r<=r){ t[p].sum=(t[p].sum+k*(t[p].r-t[p].l+1))%mod; t[p].lazy=(t[p].lazy+k)%mod; return; } int mid=(t[p].l+t[p].r)/2; pushdown(p); if(l<=mid) add(ls,l,r,k); if(r>mid) add(rs,l,r,k); pushup(p); } int ask(int p,int l,int r){ pushdown(p); if(t[p].l>=l&&t[p].r<=r){ return t[p].sum%mod; } int val=0; int mid=(t[p].l+t[p].r)/2; if(l<=mid) val=(val+ask(ls,l,r))%mod; if(r>mid) val=(val+ask(rs,l,r))%mod; return val%mod; } void addpath(int x,int y,int k){ while(top[x]!=top[y]){ if(dpt[top[x]]<dpt[top[y]]) swap(x,y); add(1,idx[top[x]],idx[x],k); x=fa[top[x]]; } if(dpt[x]>dpt[y]) swap(x,y); add(1,idx[x],idx[y],k); } int askpath(int x,int y){ int sum=0; while(top[x]!=top[y]){ if(dpt[top[x]]<dpt[top[y]]) swap(x,y); sum=(sum+ask(1,idx[top[x]],idx[x]))%mod; x=fa[top[x]]; } if(dpt[x]>dpt[y]) swap(x,y); sum=(sum+ask(1,idx[x],idx[y]))%mod; return sum; } void addtree(int x,int k){ add(1,idx[x],idx[x]+size[x]-1,k); return; } int asktree(int x){ int sum=0; sum=ask(1,idx[x],idx[x]+size[x]-1)%mod; return sum; } int main(){ n=read(),m=read(),r=read(),mod=read(); for(rint i=1;i<=n;i++) pre[i]=read(); for(rint i=1;i<n;i++){ int a=read(),b=read(); add(a,b),add(b,a); } dfs1(r,0,1); dfs2(r,r); build(1,1,n); while(m--){ int opt=read(); switch(opt){ case 1:{ int x=read(),y=read(),z=read(); z=z%mod; addpath(x,y,z); break; } case 2:{ int x=read(),y=read(); int ans=askpath(x,y); printf("%d\n",ans); break; } case 3:{ int x=read(),z=read(); z=z%mod; addtree(x,z); break; } case 4:{ int x=read(); int ans=asktree(x); printf("%d\n",ans); break; } } } return 0; } ```
by RoRoyyy @ 2019-08-03 09:18:01


不是$add(1,top[x],x,k)$ 设节点在线段树中的位置为seg[x], 则应该是$add(1,seg[top[x]],seg[x],k)$ 其他同理
by mzgwty @ 2019-08-03 09:19:46


emming
by mzgwty @ 2019-08-03 09:21:16


@[Old_Wang](/space/show?uid=79075) 改过了还wa
by RoRoyyy @ 2019-08-03 09:21:52


显然手机打字太慢了
by mzgwty @ 2019-08-03 09:21:54


@[Old_Wang](/space/show?uid=79075) 还有啥问题么....
by RoRoyyy @ 2019-08-03 09:25:01


lazy标记没放错位置吗
by Mr_Skirt @ 2019-08-03 09:26:33


@[Mr_Skirt](/space/show?uid=36956) 哪处
by RoRoyyy @ 2019-08-03 09:27:18


| 下一页