BZOJ 4817: [Sdoi2017]树点涂色 LCT+Access的性质+DFS序+线段树
作者:互联网
Code:
#include<bits/stdc++.h> #define maxn 200003 #define inf -1000000 using namespace std; void setIO(string s) { string in=s+".in",out=s+".out"; freopen(in.c_str(),"r",stdin); freopen(out.c_str(),"w",stdout); } int tim,edges,n,Q,_curcol; int dfn[maxn],ln[maxn],fa[maxn],hd[maxn],to[maxn<<1],nex[maxn<<1]; int st[maxn],ed[maxn],top[maxn],hson[maxn],siz[maxn],dep[maxn]; void addedge(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } namespace tr { int maxv[maxn<<2],lazy[maxn<<2]; void mark(int x,int k) { lazy[x]+=k, maxv[x]+=k; } void pushdown(int l,int r,int x) { if(!lazy[x]) return; int mid=(l+r)>>1; if(mid>=l) mark(x<<1,lazy[x]); if(r>mid) mark((x<<1)|1,lazy[x]); lazy[x]=0; } void update(int l,int r,int x,int L,int R,int k) { if(l>=L&&r<=R) { mark(x,k); return; } pushdown(l,r,x); int mid=(l+r)>>1; if(L<=mid) update(l,mid,x<<1,L,R,k); if(R>mid) update(mid+1,r,(x<<1)|1,L,R,k); maxv[x]=max(maxv[x<<1],maxv[(x<<1)|1]); } int query(int l,int r,int x,int L,int R) { if(l>=L&&r<=R) return maxv[x]; pushdown(l,r,x); int mid=(l+r)>>1, tmp=inf; if(L<=mid) tmp=max(tmp,query(l,mid,x<<1,L,R)); if(R>mid) tmp=max(tmp,query(mid+1,r,(x<<1)|1,L,R)); return tmp; } int po(int l,int r,int x,int k) { if(l==r) return maxv[x]; int mid=(l+r)>>1; pushdown(l,r,x); if(k<=mid) return po(l,mid,x<<1,k); else return po(mid+1,r,(x<<1)|1,k); } }; namespace tree { #define lson ch[x][0] #define rson ch[x][1] #define get(x) (ch[f[x]][1]==x) #define isrt(x) (!(ch[f[x]][0]==x||ch[f[x]][1]==x)) int ch[maxn][2],f[maxn],col[maxn],sta[maxn]; void pushdown(int x) { if(!x) return; if(col[x]) { if(lson) col[lson]=col[x]; if(rson) col[rson]=col[x]; } } int findrt(int x) { while(lson)x=lson; return x; } void rotate(int x) { int old=f[x],fold=f[old],which=get(x); if(!isrt(old)) ch[fold][ch[fold][1]==old]=x; ch[old][which]=ch[x][which^1], f[ch[old][which]]=old; ch[x][which^1]=old,f[old]=x,f[x]=fold; } void splay(int x) { int u=x,v=0,fa; sta[++v]=u; while(!isrt(u)) sta[++v]=f[u],u=f[u]; while(v) pushdown(sta[v--]); for(u=f[u];(fa=f[x])!=u;rotate(x)) if(f[fa]!=u) rotate(get(fa)==get(x)?fa:x); } void Access(int x,int co) { int t=0,son; while(x) { splay(x); if(t) son=findrt(t), tr::update(1,n,1,st[son],ed[son],-1); if(rson) son=findrt(rson),tr::update(1,n,1,st[son],ed[son],1); col[x]=co,rson=t,t=x,x=f[x]; } } }; void dfs1(int u,int ff) { fa[u]=ff; siz[u]=1; dep[u]=dep[ff]+1; ln[++tim]=u; dfn[u]=st[u]=tim; tr::update(1,n,1,dfn[u],dfn[u],dep[u]); tree::f[u]=ff; for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==ff) continue; dfs1(v,u); siz[u]+=siz[v]; if(siz[v]>siz[hson[u]]) hson[u]=v; } ed[u]=tim; } void dfs2(int u,int tp) { top[u]=tp; if(hson[u]) dfs2(hson[u],tp); for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==hson[u]||v==fa[u]) continue; dfs2(v,v); } } int LCA(int x,int y) { while(top[x]^top[y]) dep[top[x]] < dep[top[y]] ? y = fa[top[y]] : x = fa[top[x]]; return dep[x] < dep[y] ? x : y; } int main() { // setIO("input"); scanf("%d%d",&n,&Q); tr::maxv[0]=inf; for(int i=1,u,v;i<n;++i) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } dfs1(1,0); dfs2(1,1); int opt,x,y,lca,ou=0; while(Q--) { scanf("%d",&opt); switch(opt) { case 1 : { scanf("%d",&x); tree::Access(x,++_curcol); break; } case 2 : { scanf("%d%d",&x,&y); lca=LCA(x,y); ou=0; ou+=tr::po(1,n,1,dfn[x]); ou+=tr::po(1,n,1,dfn[y]); ou-=tr::po(1,n,1,dfn[lca])<<1; ou+=1; printf("%d\n",ou); break; } case 3 : { scanf("%d",&x); printf("%d\n",tr::query(1,n,1,st[x],ed[x])); break; } } } return 0; }
标签:hson,dep,LCT,4817,int,top,fa,maxn,涂色 来源: https://www.cnblogs.com/guangheli/p/11027343.html