树链剖分,线段树全MLE求调

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

有没有一种可能,我是说可能,您的 mid 的宏定义少了个 `()`
by Zvelig1205 @ 2022-07-23 20:16:50


有没有另一种可能,`dfs` 里应该是 ```cpp for(int i=head[x],v;i!=-1;i=e[i].nxt) ```
by Zvelig1205 @ 2022-07-23 20:22:24


@[极冬寒雪](/user/413020) 对,是的没错,sos第一点我之前完全没有注意到,谢谢大佬!!
by Susking @ 2022-07-23 20:30:01


@[Susking](/user/584977) 还发现两处错误: 1. 25行最后 2. 78行去掉 ll
by Zvelig1205 @ 2022-07-23 20:35:03


但还是没过样例![](//图.tk/j)
by Zvelig1205 @ 2022-07-23 20:35:42


话说,您的build好像不怎么对吧……
by Zvelig1205 @ 2022-07-23 20:39:48


为什么要对tim建树?不应该对按时间戳下放的数组建树吗?
by Zvelig1205 @ 2022-07-23 20:41:13


@[Susking](/user/584977) 过样例: ```cpp #include<bits/stdc++.h> #define ll long long #define MN 100020 #define zuo x<<1 #define mid ((l+r)>>1) #define you (x<<1)+1 using namespace std; int N,M,RR ,op,x,y,z,L,R , head[MN]; ll P ,W [MN], ans; int deep[MN],siz[MN],son[MN],fa[MN],top[MN]; int tim[MN],t; ll sum[5*MN],lazy[5*MN]; struct edge{ int to,nxt; }e[MN*2]; void build(int l,int r,int x){ if(l==r){sum[x]=W[tim[l]]%P ;return ;} build(l,mid,zuo); build(mid+1,r,you); sum[x]=(sum[zuo]+sum[you])%P ; } void pushdown(int l,int r,int x){ if(lazy[x]){ sum[zuo]+=(mid-l+1)%P *lazy[x]%P ; sum[you]+=(r-mid)%P *lazy[x]%P ; lazy[zuo]+=lazy[x]%P ; lazy[you]+=lazy[x ]%P; lazy[x]=0; } } void add(int l,int r,int x){ if(L<=l &&r<=R){ sum[x]+=(r-l+1)*z%P ; lazy[x]+=z%P ; return ; } if(lazy[x]) pushdown(l,r,x); if(mid>=L) add(l,mid,zuo); if(R>mid)add(mid+1,r,you); sum[x]=(sum[zuo]+sum[you])%P ; } void query(int l,int r,int x){ if(L<=l &&r<=R){ans=(ans+sum[x])%P ;return ;} if(lazy[x]) pushdown(l,r,x); if(mid>=L) query(l,mid,zuo); if(R>mid) query(mid+1,r,you); } void dfs1(int x,int dep){ int ms=0; deep[x]=dep;siz[x]=1; for(int i=head[x],v;i!=-1;i=e[i].nxt){ v=e[i].to; if(v==fa[x]) continue; fa[v]=x; dfs1(v,dep+1); siz[x]+=siz[v]; if(ms<siz[v]) son[x]=v,ms=siz[v]; } } void dfs2(int x,int tp){ top[x]=tp;tim[++t]=x; if(!son[x]) return ; dfs2(son[x],tp); for(int i=head[x],v;i!=-1;i=e[i].nxt){ v=e[i].to; if(v==fa[x] ||v==son[x]) continue; dfs2(v,v); } } void wayadd(){ while(top[x]!=top[y]){ if(deep[top[x]]<deep[top[y]]) swap(x,y); L=tim[top[x]];R=tim[x]; add(1,N,1); x=fa[top[x]]; } if(deep[x]<deep[y]) swap(x,y); L=tim[y];R=tim[x]; add(1,N,1); } void waysum(){ ans=0; while(top[x]!=top[y]){ if(deep[top[x]]<deep[top[y]]) swap(x,y); L=tim[top[x]];R=tim[x]; query(1,N,1); x=fa[top[x]]; } if(deep[x]<deep[y]) swap(x,y); L=tim[y];R=tim[x]; query(1,N,1); printf("%lld",ans%P); } int main(){ memset(head,-1,sizeof(head)); scanf("%d%d%d%lld",&N ,&M ,&RR ,&P); ++M ; for(ll i=1;i<=N;++i) scanf("%lld",&W[i]); for(ll i=0,xx,yy;i<(N-1)<<1;i+=2){ scanf("%lld%lld",&xx,&yy); e[i].to=yy;e[i].nxt=head[xx];head[xx]=i; e[i^1].to=xx;e[i^1].nxt=head[yy];head[yy]=i^1; } dfs1(RR,1); dfs2(RR,RR); build(1,N,1); while(--M){ scanf("%d%d",&op,&x); switch(op){ case 1:scanf("%d%d",&y,&z),wayadd();break; case 2:scanf("%d",&y),waysum();break; case 3:scanf("%d",&z),L=tim[x],R=tim[x]+siz[x]-1,add(1,N,1);break; case 4:L=tim[x],R=tim[x]+siz[x]-1,query(1,N,1),printf("%lld\n",ans);break; } } } ```
by Zvelig1205 @ 2022-07-23 20:43:22


@[极冬寒雪](/user/413020) 超,确实,我是蒟蒻() 感谢大佬!!!我打算重构代码,太多错误了sossos
by Susking @ 2022-07-23 20:55:55


|