蒟蒻求助(10分)

P3976 [TJOI2015] 旅游

我看看,我现在就发现了一个问题,修改不push_up
by xiao7_Mr_10_ @ 2023-12-15 19:33:22


调好了,你太粗心了,push_up没写然后你那个分类讨论有问题,我给你重写了,代码没多少变动: ```cpp #include <bits/stdc++.h> using namespace std; const int N=2e5+5; const int inf=1e9+7; vector<int>e[N]; struct Tree{ long long maxx,minn,max1/*l~r*/,max2/*r~l*/,o; }t[N]; long long f[N],son[N],w[N],wd[N],id[N],siz[N],top[N],dep[N],cnt; void dfs1(long long x,long long fa){ f[x]=fa; dep[x]=dep[fa]+1; siz[x]=1; for(long long i=0;i<e[x].size();i++){ if(e[x][i]!=fa){ dfs1(e[x][i],x); if(siz[e[x][i]]>siz[son[x]])son[x]=e[x][i]; siz[x]+=siz[e[x][i]]; } } } void dfs2(long long x,long long tp){ top[x]=tp; cnt++; id[x]=cnt; wd[cnt]=w[x]; if(son[x]==0)return; dfs2(son[x],tp); for(long long i=0;i<e[x].size();i++){ if(e[x][i]!=f[x]&&e[x][i]!=son[x]){ dfs2(e[x][i],e[x][i]); } } } void updata(long long z){ t[z].minn=min(t[z<<1].minn,t[z<<1|1].minn); t[z].maxx=max(t[z<<1].maxx,t[z<<1|1].maxx); t[z].max1=max(t[z<<1].max1,max(t[z<<1|1].max1,t[z<<1|1].maxx-t[z<<1].minn)); t[z].max2=max(t[z<<1].max2,max(t[z<<1|1].max2,t[z<<1].maxx-t[z<<1|1].minn)); } void build(long long l,long long r,long long z){ if(l==r){ t[z].minn=wd[l]; t[z].maxx=wd[l]; return; } long long mid=(l+r)>>1; build(l,mid,z<<1); build(mid+1,r,z<<1|1); updata(z); } void push_down(long long z){ if(t[z].o!=0){ t[z<<1].o+=t[z].o; t[z<<1|1].o+=t[z].o; t[z<<1].maxx+=t[z].o; t[z<<1|1].maxx+=t[z].o; t[z<<1].minn+=t[z].o; t[z<<1|1].minn+=t[z].o; t[z].o=0; } } void xg(long long l,long long r,long long x,long long y,long long z,long long k){ if(l<=x&&y<=r){ t[z].o+=k; t[z].minn+=k; t[z].maxx+=k; return; } push_down(z); long long mid=(x+y)>>1; if(mid>=l)xg(l,r,x,mid,z<<1,k); if(mid<r)xg(l,r,mid+1,y,z<<1|1,k); updata(z); } long long jc(long long l,long long r,long long x,long long z){//查询最小值? if(l==r&&l==x){ return t[z].minn; } if(l!=r)push_down(z); long long mid=(l+r)>>1; if(mid>=x)return jc(l,mid,x,z<<1); else return jc(mid+1,r,x,z<<1|1); } Tree cx(long long l,long long r,long long x,long long y,long long z){//查询 if(l<=x&&y<=r){ return t[z]; } if(l!=r)push_down(z); long long mid=(x+y)>>1; if(mid>=l&&mid<r){ Tree a=cx(l,r,x,mid,z<<1);//l Tree b=cx(l,r,mid+1,y,z<<1|1);//r Tree ans; ans.maxx=max(a.maxx,b.maxx); ans.minn=min(a.minn,b.minn); ans.max1=max(a.max1,max(b.max1,b.maxx-a.minn)); ans.max2=max(a.max2,max(b.max2,a.maxx-b.minn)); return ans; } else if(mid>=l)return cx(l,r,x,mid,z<<1); else if(mid<r)return cx(l,r,mid+1,y,z<<1|1); } void lcaxg(long long x,long long y,long long k){//修改 while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); xg(id[top[x]],id[x],1,cnt,1,k); x=f[top[x]]; } if(dep[x]>dep[y])swap(x,y); xg(id[x],id[y],1,cnt,1,k); } long long n; long long lcacx(long long x,long long y){ long long qd=x,zd=y;//起点,终点 Tree l,r; //不是左右,只是想象成左是开头右是结尾,(不要在意变量名) //服了,线段树这么写我也不说什么,忍不了了,改成l和r了 l.max1=l.max2=0,l.minn=inf,l.maxx=-inf; r=l;//初始化,个人习惯 //你分类讨论太丑了,我重新写了,相信你不敢有意见 while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]){ Tree ans=cx(id[top[y]],id[y],1,n,1); r.max1=max(max(ans.max1,r.max1),r.maxx-ans.minn); r.max2=max(max(ans.max2,r.max2),ans.maxx-r.minn); r.maxx=max(r.maxx,ans.maxx); r.minn=min(r.minn,ans.minn); y=f[top[y]]; } else{ Tree ans=cx(id[top[x]],id[x],1,n,1); l.max1=max(max(ans.max1,l.max1),l.maxx-ans.minn); l.max2=max(max(ans.max2,l.max2),ans.maxx-l.minn); l.maxx=max(l.maxx,ans.maxx); l.minn=min(l.minn,ans.minn); x=f[top[x]]; } } if(dep[x]<dep[y]){ Tree ans=cx(id[x],id[y],1,n,1); r.max1=max(max(ans.max1,r.max1),r.maxx-ans.minn); r.max2=max(max(ans.max2,r.max2),ans.maxx-r.minn); r.maxx=max(r.maxx,ans.maxx); r.minn=min(r.minn,ans.minn); } else{ Tree ans=cx(id[y],id[x],1,n,1); l.max1=max(max(ans.max1,l.max1),l.maxx-ans.minn); l.max2=max(max(ans.max2,l.max2),ans.maxx-l.minn); l.maxx=max(l.maxx,ans.maxx); l.minn=min(l.minn,ans.minn); } int ans=max(max(l.max2,r.max1),r.maxx-l.minn); return ans; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n; for(long long i=1;i<=n;i++)cin>>w[i]; for(long long i=1;i<n;i++){ long long x,y; cin>>x>>y; e[x].push_back(y); e[y].push_back(x); } dfs1(1,0); dfs2(1,1); build(1,n,1); long long q; cin>>q; for(long long i=1;i<=q;i++){ long long a,b,u; cin>>a>>b>>u; lcaxg(a,b,u); cout << lcacx(a,b) <<"\n"; } return 0; } ```
by xiao7_Mr_10_ @ 2023-12-15 19:52:13


@[xiao7_Mr_10_](/user/961149) 谢谢,我确实太粗心了。 拜
by wang_ly_ly @ 2023-12-17 13:35:07


@[xiao7_Mr_10_](/user/961149) 为什么修改要push_up呢? 我从来不push_up 拜
by wang_ly_ly @ 2023-12-17 13:36:52


@[wang_ly_ly](/user/748723) 你区间修改不push_up,想上天?
by xiao7_Mr_10_ @ 2023-12-17 14:22:37


@[xiao7_Mr_10_](/user/961149) 那为什么我以前从来不写呢? 而且我以前又不是没a过线段树
by wang_ly_ly @ 2023-12-17 14:38:27


@[wang_ly_ly](/user/748723) 区间修改不push_up?标记永久化?这题不行的吧
by xiao7_Mr_10_ @ 2023-12-17 16:48:09


@[xiao7_Mr_10_](/user/961149) 为什么cx里有push_up会RE??
by wang_ly_ly @ 2023-12-17 23:18:34


|