LCT总结——应用篇(附题单)(LCT)
一般都是维护链的操作。split即可搞定。
进阶操作的话,处理好辅助树和原树的关系即可搞定。
其实,最大的区别就是,splay随便转,辅助树形态变了,但是原树形态不变,makert会让原树形态变化
LCT维护子树信息
真儿子会splay的时候各种变化,但是虚儿子只会在access和link的时候发生变化,其他的时候可以理解为跟着转。
以处理子树sz为例,
处理虚边子树sz,总sz(包括实边)两个
pushup注意下。
access和link注意下。
需要真正找子树信息的时候,考虑把x的后继access掉,把xsplay到根,然后总sz就是子树sz了。
模板题:
[BJOI2014]大融合
注意查询x,y的子树大小的话,makert(x),access(y),splay(y).
其实x,y直接连通,所以现在是一个长度为2的链,y是根,x是y的右儿子,然后直接(si[y]+1)*(si[x]+1)即可。(si[x]+1可以换成s[x])
#include<bits/stdc++.h> #define il inline #define reg register int #define numb (ch^'0') using namespace std; typedef long long ll; il void rd(int &x){ char ch;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } namespace Miracle{ const int N=1e5+5; int ch[N][2],fa[N],si[N],s[N]; int r[N]; int n,q; bool nrt(int x){ return (ch[fa[x]][0]==x)||(ch[fa[x]][1]==x); } void pushup(int x){ if(x) s[x]=s[ch[x][0]]+s[ch[x][1]]+si[x]+1; } void rev(int x){ swap(ch[x][0],ch[x][1]); r[x]^=1; } void pushdown(int x){ if(r[x]){ rev(ch[x][0]);rev(ch[x][1]); r[x]=0; } } void rotate(int x){ int y=fa[x],d=ch[fa[x]][1]==x; fa[ch[y][d]=ch[x][!d]]=y; if(nrt(y)) ch[fa[x]=fa[y]][ch[fa[y]][1]==y]=x; else fa[x]=fa[y]; ch[fa[y]=x][!d]=y; pushup(y); } int sta[N],top; void splay(int x){ int y=x; sta[++top]=y; while(nrt(y)) y=fa[y],sta[++top]=y; while(top) pushdown(sta[top--]); int z; while(nrt(x)){ y=fa[x],z=fa[y]; if(nrt(y)){ rotate(((ch[z][0]==y)==(ch[y][0]==x))?y:x); } rotate(x); } pushup(x); } void access(int x){ for(int y=0;x;y=x,x=fa[x]){ splay(x); si[x]-=s[y]; si[x]+=s[ch[x][1]]; ch[x][1]=y; pushup(x); } } void makert(int x){ access(x); splay(x); rev(x); } void link(int x,int y){ makert(x); makert(y); si[y]+=s[x]; s[y]+=s[x]; fa[x]=y; pushup(y); } int query(int x,int y){ makert(x);access(y); return (long long)(si[x]+1)*(si[y]+1); } int main(){ rd(n);rd(q); char cc[2]; int x,y; for(reg i=1;i<=n;++i){ si[i]=0;s[i]=1; } while(q--){ scanf("%s",cc+1); rd(x);rd(y); if(cc[1]=='A'){ link(x,y); }else{ printf("%d\n",query(x,y)); } } return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* Date: 2018/12/18 11:13:18 */
LCT维护联通块信息(边双联通分量)
LCT维护边权(常用生成树)
LCT维护子树信息
LCT维护树上染色联通块