[BZOJ4817][SDOI2017]树点涂色
2018-01-23 11:39
274 查看
BZOJ
Luogu
你会发现操作1神似\(LCT\)中的\(access\)
考虑在某一次1操作中,会有若干组父子关系,有的是父子从同色变成了异色,有的是从异色变成了同色。如果我们就把同色的点放在一棵splay里面,那操作就直接对应\(access\)操作了。
我们考虑维护这个东西:每个点到根的路径权值\(val_i\)
如果一对父子的颜色从同色变成异色,那么原树中以那个儿子为根的子树的每个点的权值都会加一;反之,若从异色变同色,那么就会全部减一。而对应到\(access\)中,由同变异的刚好是原实儿子,由异变同的刚好是新实儿子。
子树转化成区间,然后就是经典线段树操作。
对于操作2,答案是\(val_x+val_y-2*val_{lca(u,v)}+1\)
所以你需要写LCA+LCT+支持区间加和区间查最大值的线段树
注意:在\(access\)中,打标记的位置是链顶!
所以要在splay中暴跳一下左儿子找到最左边那个点
线段树可以标记永久化
LCT只要写\(access\),连\(rev\)都不用打
Luogu
sol
这个题只要你想清楚了就变成码农题了。你会发现操作1神似\(LCT\)中的\(access\)
考虑在某一次1操作中,会有若干组父子关系,有的是父子从同色变成了异色,有的是从异色变成了同色。如果我们就把同色的点放在一棵splay里面,那操作就直接对应\(access\)操作了。
我们考虑维护这个东西:每个点到根的路径权值\(val_i\)
如果一对父子的颜色从同色变成异色,那么原树中以那个儿子为根的子树的每个点的权值都会加一;反之,若从异色变同色,那么就会全部减一。而对应到\(access\)中,由同变异的刚好是原实儿子,由异变同的刚好是新实儿子。
子树转化成区间,然后就是经典线段树操作。
对于操作2,答案是\(val_x+val_y-2*val_{lca(u,v)}+1\)
所以你需要写LCA+LCT+支持区间加和区间查最大值的线段树
注意:在\(access\)中,打标记的位置是链顶!
所以要在splay中暴跳一下左儿子找到最左边那个点
code
LCA沉迷树链剖分无法自拔线段树可以标记永久化
LCT只要写\(access\),连\(rev\)都不用打
#include<cstdio> #include<algorithm> using namespace std; const int N = 100005; int gi() { int x=0,w=1;char ch=getchar(); while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if (ch=='-') w=0,ch=getchar(); while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return w?x:-x; } struct edge{int to,next;}a[N<<1]; int n,m,head ,cnt,pa ,dep ,sz ,son ,top ,dfn ,low ; void dfs1(int u,int f) { pa[u]=f;dep[u]=dep[f]+1;sz[u]=1; for (int e=head[u];e;e=a[e].next) { int v=a[e].to;if (v==f) continue; dfs1(v,u); sz[u]+=sz[v];if (sz[v]>sz[son[u]]) son[u]=v; } } void dfs2(int u,int up) { top[u]=up;dfn[u]=++cnt; if (son[u]) dfs2(son[u],up); for (int e=head[u];e;e=a[e].next) if (a[e].to!=pa[u]&&a[e].to!=son[u]) dfs2(a[e].to,a[e].to); low[u]=cnt; } int getlca(int u,int v) { while (top[u]^top[v]) { if (dep[top[u]]<dep[top[v]]) swap(u,v); u=pa[top[u]]; } return dep[u]<dep[v]?u:v; } int tag[N<<2],mx[N<<2]; void Modify(int x,int l,int r,int ql,int qr,int v) { if (l>=ql&&r<=qr) { tag[x]+=v;mx[x]+=v; return; } int mid=l+r>>1; if (ql<=mid) Modify(x<<1,l,mid,ql,qr,v); if (qr>mid) Modify(x<<1|1,mid+1,r,ql,qr,v); mx[x]=max(mx[x<<1],mx[x<<1|1])+tag[x]; } int Query(int x,int l,int r,int ql,int qr) { if (l>=ql&&r<=qr) return mx[x]; int mid=l+r>>1,s=-1e9; if (ql<=mid) s=max(s,Query(x<<1,l,mid,ql,qr)); if (qr>mid) s=max(s,Query(x<<1|1,mid+1,r,ql,qr)); return s+tag[x]; } int fa ,ls ,rs ; bool isroot(int x){return ls[fa[x]]!=x&&rs[fa[x]]!=x;} void R_rotate(int x) { int y=fa[x],z=fa[y]; ls[y]=rs[x]; if (rs[x]) fa[rs[x]]=y; fa[x]=z; if (y==ls[z]) ls[z]=x;if (y==rs[z]) rs[z]=x; rs[x]=y;fa[y]=x; } void L_rotate(int x) { int y=fa[x],z=fa[y]; rs[y]=ls[x]; if (ls[x]) fa[ls[x]]=y; fa[x]=z; if (y==ls[z]) ls[z]=x;if (y==rs[z]) rs[z]=x; ls[x]=y;fa[y]=x; } void splay(int x) { while (!isroot(x)) { int y=fa[x],z=fa[y]; if (isroot(y)) if (x==ls[y]) R_rotate(x); else L_rotate(x); else if (y==ls[z]) if (x==ls[y]) R_rotate(y),R_rotate(x); else L_rotate(x),R_rotate(x); else if (x==ls[y]) R_rotate(x),L_rotate(x); else L_rotate(y),L_rotate(x); } } int getf(int x){while(ls[x])x=ls[x];return x;} void access(int x) { int gg; for (int y=0;x;y=x,x=fa[x]) { splay(x); if (rs[x]) gg=getf(rs[x]),Modify(1,1,n,dfn[gg],low[gg],1); if (y) gg=getf(y),Modify(1,1,n,dfn[gg],low[gg],-1); rs[x]=y; } } int main() { n=gi();m=gi(); for (int i=1,u,v;i<n;i++) { u=gi();v=gi(); a[++cnt]=(edge){v,head[u]};head[u]=cnt; a[++cnt]=(edge){u,head[v]};head[v]=cnt; } dfs1(1,0);cnt=0;dfs2(1,1); for (int i=1;i<=n;i++) fa[i]=pa[i],Modify(1,1,n,dfn[i],low[i],1); while (m--) { int opt=gi(),x=gi(),y,gg; if (opt==1) access(x); if (opt==2) { y=gi(); gg=getlca(x,y); printf("%d\n",Query(1,1,n,dfn[x],dfn[x])+Query(1,1,n,dfn[y],dfn[y])-2*Query(1,1,n,dfn[gg],dfn[gg])+1); } if (opt==3) printf("%d\n",Query(1,1,n,dfn[x],low[x])); } return 0; }
相关文章推荐
- BZOJ4817 [Sdoi2017]树点涂色(洛谷P3703)
- bzoj4817 [Sdoi2017]树点涂色
- bzoj4817 [Sdoi2017]树点涂色
- [BZOJ4817][SDOI2017]树点涂色(LCT+线段树+差分)
- [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)
- 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树
- BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树
- [bzoj4817][Sdoi2017]树点涂色
- [LCT] BZOJ 4817 [Sdoi2017]树点涂色
- bzoj4817 [Sdoi2017]树点涂色
- Bzoj4817 [Sdoi2017]树点涂色
- [BZOJ4817][SDOI2017]树点涂色(DFS序+LCA+树剖+LCT)
- [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)
- 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]
- BZOJ4817 [Sdoi2017]树点涂色
- 【bzoj4817】[Sdoi2017]树点涂色 LCT+LCA+线段树
- 【BZOJ4817】【SDOI2017】树点染色
- BZOJ 4818: [Sdoi2017]序列计数
- 【BZOJ 4816】【SDOI 2017】数字表格
- 洛谷P3703 [SDOI2017]树点涂色