[BZOJ1984]月下“毛景树”(树链剖分)
2018-03-12 23:30
246 查看
题目:
我是超链接题解:
这个题一眼链剖了,但是有两个特殊的地方一个是使用了边权,这个的处理方法就是把边权放在较深的点上,这样做会导致root没有意义了,区别就是在查询链和修改链的时候最后一步剩下的肯定是一个根节点和ta的重儿子支下的一点(例外是两个根节点,这种情况直接退出),那么最后一步我们就查询/修改根节点的重儿子和支下的那个点就好了(也就是强行排除根节点)
另一个是有一个add标记和一个delta标记分别表示添加和覆盖,我们的处理方法就是。add是新的时候,如果有delta,add就别管了,给delta累上值。delta是新的时候,如果有add,全部赋成0。注意不光是change操作的时候要这样做,pushdown的时候也要这样做,因为两个都有新旧操作的差别
代码:
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int N=100005; int tot,nxt[N*2],point ,v[N*2],fa ,h ,in ,out ,top ,jl ; int n,delta[N*4],son ,maxx[N*4],root,size ,totw,a ,tree ,add[N*4]; void addline(int x,int y) { ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; ++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x; } void dfs_1(int x,int faa) { fa[x]=faa;h[x]=h[faa]+1;size[x]=1;int maxx=0; for (int i=point[x];i;i=nxt[i]) if (v[i]!=faa) { dfs_1(v[i],x); size[x]+=size[v[i]]; if (maxx<size[v[i]]) maxx=size[v[i]],son[x]=v[i]; } } void dfs_2(int x,int fa) { if (son[fa]!=x) top[x]=x; else top[x]=top[fa]; in[x]=++totw; if (son[x]) { dfs_2(son[x],x); for (int i=point[x];i;i=nxt[i]) 4000 if (v[i]!=fa && v[i]!=son[x]) dfs_2(v[i],x); } } void updata(int now){maxx[now]=max(maxx[now<<1],maxx[now<<1|1]);} void pushdown(int now) { if (delta[now]!=-1) { add[now<<1]=add[now<<1|1]=0; delta[now<<1]=delta[now]; delta[now<<1|1]=delta[now]; maxx[now<<1]=delta[now]; maxx[now<<1|1]=delta[now]; delta[now]=-1; } if (add[now]) { if (delta[now<<1]!=-1) delta[now<<1]+=add[now]; else add[now<<1]+=add[now]; if (delta[now<<1|1]!=-1) delta[now<<1|1]+=add[now]; else add[now<<1|1]+=add[now]; maxx[now<<1]+=add[now]; maxx[now<<1|1]+=add[now]; add[now]=0; } } void build(int now,int l,int r) { if (l==r) { maxx[now]=a[tree[l]]; return; } int mid=(l+r)>>1; build(now<<1,l,mid); build(now<<1|1,mid+1,r); updata(now); } void change(int now,int l,int r,int lrange,int rrange,int vv,int id) { if (lrange<=l && rrange>=r) { if (id==1) { delta[now]=vv; maxx[now]=vv; if (add[now]) add[now]=0; } else { maxx[now]+=vv; if (delta[now]!=-1) delta[now]+=vv;else add[now]+=vv; } return; } int mid=(l+r)>>1; pushdown(now); if (lrange<=mid) change(now<<1,l,mid,lrange,rrange,vv,id); if (rrange>mid) change(now<<1|1,mid+1,r,lrange,rrange,vv,id); updata(now); } int qurry(int now,int l,int r,int lrange,int rrange) { if (lrange<=l && rrange>=r) return maxx[now]; int mid=(l+r)>>1,ans=0; pushdown(now); if (lrange<=mid) ans=max(ans,qurry(now<<1,l,mid,lrange,rrange)); if (rrange>mid) ans=max(ans,qurry(now<<1|1,mid+1,r,lrange,rrange)); return ans; } void Chan(int u,int v,int vv,int id) { int f1=top[u],f2=top[v]; while (f1!=f2) { if (h[f1]<h[f2]) swap(f1,f2),swap(u,v); change(1,1,n,in[f1],in[u],vv,id); u=fa[f1]; f1=top[u]; } if (u==v) return; if (in[u]>in[v]) swap(u,v); change(1,1,n,in[son[u]],in[v],vv,id); } void Qu(int u,int v) { int f1=top[u],f2=top[v],maxx=0; while (f1!=f2) { if (h[f1]<h[f2]) swap(f1,f2),swap(u,v); maxx=max(maxx,qurry(1,1,n,in[f1],in[u])); u=fa[f1]; f1=top[u]; } if (u==v) {printf("%d\n",maxx);return;} if (in[u]>in[v]) swap(u,v); maxx=max(maxx,qurry(1,1,n,in[son[u]],in[v])); printf("%d\n",maxx); } int main() { memset(delta,-1,sizeof(delta)); scanf("%d",&n); for (int i=1;i<n;i++) { int x,y,z;scanf("%d%d%d",&x,&y,&z); addline(x,y);if (x>y) swap(x,y);a[y]=z; jl[i]=y; } dfs_1(1,0); dfs_2(1,0); for (int i=1;i<=n;i++) tree[in[i]]=i; build(1,1,n);char st[10]; while (scanf("%s",st) && st[0]!='S') { int x,y,v; if (st[0]=='C' && st[1]=='h') { scanf("%d%d",&x,&v); change(1,1,n,in[jl[x]],in[jl[x]],v,1); continue; } if (st[0]=='C' && st[1]=='o') { scanf("%d%d%d",&x,&y,&v); Chan(x,y,v,1); continue; } if (st[0]=='A') { scanf("%d%d%d",&x,&y,&v); Chan(x,y,v,2); continue; } if (st[0]=='M') { scanf("%d%d",&x,&y); Qu(x,y); } } }
相关文章推荐
- bzoj1984 月下“毛景树”树链剖分 线段树
- [BZOJ1984]月下“毛景树”解题报告|树链剖分
- [BZOJ1984] 月下“毛景树”|树链剖分|线段树
- Bzoj 1984: 月下“毛景树” 树链剖分
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
- BZOJ 1984: 月下“毛景树”( 树链剖分 )
- 【树链剖分】【分块】【最近公共祖先】【块状树】bzoj1984 月下“毛景树”
- 【BZOJ1984】月下“毛景树”-树链剖分
- [BZOJ1984]月下“毛景树”(树链剖分)
- 【BZOJ-1984】月下“毛景树” 树链剖分
- [bzoj1984]月下“毛景树” 树链剖分
- bzoj 1984: 月下“毛景树” (树链剖分)
- BZOJ 1984 月下“毛景树” 树链剖分
- 【BZOJ1984】月下“毛景树” 树链剖分+线段树
- 【bzoj1984】【坑】月下“毛景树” 树链剖分
- bzoj1984 月下“毛景树”(边权的树链剖分)
- bzoj 1984: 月下“毛景树”
- bzoj 1984: 月下“毛景树” 线段树+树链剖分
- bzoj1984 月下“毛景树”
- [BZOJ]1984: 月下“毛景树”