可爱线段树合并板子WA#4&TLE#18~20求调

P4556 [Vani有约会] 雨天的尾巴 /【模板】线段树合并

@[vicky128](/user/177000) 你吗的那个求助帖删掉了 我不是帮你把代码调过了吗 看看我帮你调的代码呗 ```cpp #include<bits/stdc++.h> //坏习惯:这里不要用 define,用 const 更安全 const int N=1e5+5,T=N*80; #define L lc[no] #define R rc[no] //好习惯:这份 define 安全一些 using namespace std; int n,m,sz[N],son[N],dep[N],fa[N],t[N],r[N],cnt,bh,fir[N],z[N],len,lsh[N],op[N],x[N],y[N]; struct E{ int nex,to;}e[N<<1]; struct tree{ int lc[T],rc[T],tot[T],num[T]; //inline 在开高版本编译器的情况下无必要 //编译器比你更懂开 inline ——danielQF void pushup(int no){ num[no]=0; if(tot[L]>=tot[R])num[no]=num[L],tot[no]=tot[L]; else num[no]=num[R],tot[no]=tot[R];} void ins(int &no,int l,int r,int pl,int k){ if(pl>r||pl<l) return ; if(!no) no=++bh; // tot[no]+=k; //卧槽,你维护这个东西干嘛 if(l==r){ tot[no]+=k;num[no]=lsh[l]; return ;} //离散化,较为符合本人做法 int mi=l+r>>1; ins(L,l,mi,pl,k); ins(R,mi+1,r,pl,k); pushup(no); //tot[no]=tot[L]+tot[R]; //上面这一行完全没有必要加 //因为你在前面已经 tot[no]+=k 了 } void merge(int &no,int r2,int l,int r){ // if(!r2) return ; // if(!no){ no=r2; return ;} if(!no||!r2)return no|=r2,void(); //我一般的写法如上 if(l==r){ tot[no]+=tot[r2]; return ;} int mi=l+r>>1; merge(L,lc[r2],l,mi); merge(R,rc[r2],mi+1,r); pushup(no); //上面三行重复,建议直接封装成一个成型的 pushup } }tr; //看起来你的线段树没有什么问题 int lca(int,int); void add(int,int),cf(int,int,int),dfs(int),dfs2(int,int),dfs3(int); //卧槽 int ans[N]; signed main(){ ios::sync_with_stdio(0);cin.tie(0); //可以不用 scanf,用 cin //cin 在 取消同步流的情况下 效率比 scanf 还要快 //我本人在 CSP 结束后发现的 cin>>n>>m; len=m; for(int i=1,a,b;i<n;++i){ cin>>a>>b; add(a,b); } dfs(1),dfs2(1,1); for(int i=1;i<=m;++i){ cin>>x[i]>>y[i]>>z[i]; lsh[i]=z[i]; } sort(lsh+1,lsh+1+len); len=unique(lsh+1,lsh+1+len)-lsh-1; //离散化,没有问题 for(int i=1;i<=len;++i) op[lsh[i]]=i; for(int i=1;i<=m;++i) cf(x[i],y[i],op[z[i]]); dfs3(1); for(int i=1;i<=n;++i) // printf("%d\n",tr.num[r[i]]); // 破案了 //应该在 dfs3 的过程及时记录答案 //可持久化线段树合并见 https://www.luogu.com.cn/blog/SmallTualatin/p4094 printf("%d\n",ans[i]); //应该改为以下代码 return 0; } void add(int a,int b){ e[++cnt].nex=fir[a],e[cnt].to=b,fir[a]=cnt; e[++cnt].nex=fir[b],e[cnt].to=a,fir[b]=cnt; } void dfs(int no){ ++sz[no]; for(int i=fir[no];i;i=e[i].nex){ int v=e[i].to; if(v==fa[no]) continue; dep[v]=dep[no]+1; fa[v]=no; dfs(v); sz[no]+=sz[v]; if(sz[v]>sz[son[no]]) son[no]=v; } } void dfs2(int no,int to){ t[no]=to; if(!son[no]) return ; dfs2(son[no],to); for(int i=fir[no];i;i=e[i].nex){ int v=e[i].to; if(v!=fa[no]&&v!=son[no]) dfs2(v,v); } } int lca(int a,int b){ //看得不爽,代码给你全扬了 for(;t[a]^t[b];a=fa[t[a]]) if(dep[t[a]]<dep[t[b]])swap(a,b); return dep[a]<dep[b]?a:b; } void cf(int x,int y,int z){ int lc=lca(x,y); // printf("x=%d y=%d lc=%d\n",x,y,lc); tr.ins(r[x],1,len,z,1); tr.ins(r[y],1,len,z,1); tr.ins(r[lc],1,len,z,-1); if(fa[lc]) tr.ins(r[fa[lc]],1,len,z,-1); } void dfs3(int no){ for(int i=fir[no];i;i=e[i].nex){ int v=e[i].to; if(v==fa[no]) continue; dfs3(v); tr.merge(r[no],r[v],1,len); } //啊啊啊?你他妈 merge r[0] 干嘛? // tr.merge(r[no],r[0],1,len); ans[no]=tr.tot[r[no]]?tr.num[r[no]]:0; } ``` ~~验证码 3cnm 祭~~
by SMT0x400 @ 2024-01-24 16:34:28


~~文明一点jbl~~
by syr1125 @ 2024-01-24 16:57:35


@[SMT0x400](/user/121995) yyf这么细
by 普通的名字 @ 2024-01-24 20:13:34


@[普通的名字](/user/335482) 梦老师也来凑热闹?
by zswangziye @ 2024-01-24 20:17:36


@[普通的名字](/user/335482) 毕竟对方是 vicky
by SMT0x400 @ 2024-01-24 20:19:01


|