【模板】LCT+理解

原来一直不知道LCT是干什么的。。。只知道是动态树剖。。。(现在看好像也不是那么像了。。。)

核心:用一丛平衡树维护一棵无根树。。。

因为SPLAY与LCT相性最好。。。(个人感觉。。。毕竟还没看到拿TREAP写的。。。(PS:我孤陋寡闻。。。));

所以用SPLAY维护!!!

核心++:把一棵树剖成许多链。。。一条长度为log(n)的链是一棵SPLAY(关键字:dep)

所以SPLAY最左端就是root!!!


#include<cstdio>
#include<iostream>
#define MAXN 10005 
using namespace std;

int ch[MAXN][2],fa[MAXN];
int lazy[MAXN],num[MAXN];

inline bool root(int x)
{return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}

void rotate(int x)
{
  int y=fa[x],z=fa[y];
  int d=ch[y][0]==x ? 0:1;
  if(!root(y))
  {
    if(ch[z][0]==y)ch[z][0]=x;
    else ch[z][1]=x;        
  }
  fa[y]=x,fa[x]=z,fa[ch[x][d^1]]=y;
  ch[y][d]=ch[x][d^1],ch[x][d^1]=y;
}

inline void down(int x)
{
  if(!lazy[x])return ;
  lazy[x]^=1,lazy[ch[x][0]]^=1,lazy[ch[x][1]]^=1;
  swap(ch[x][0],ch[x][1]);       
}

void up(int x)                                         ///注意先把标记传完。。。否则会T。。。不知原因。。。
{
  if(!root(x))up(fa[x]);
  down(x);     
}

void splay(int x)
{
  up(x);
  int y,z;
  while(!root(x))
  {
    y=fa[x],z=fa[y];
    down(y);down(x);
    if(!root(y))
    {
      if((ch[z][0]==y)^(ch[y][0]==x))rotate(x);
      else rotate(y);            
    }               
    rotate(x);
  }
  down(x);
}

int pos[MAXN],poi=0;

void access(int x)
{
  int t=0;
  while(x)
  {
    splay(x);
    ch[x][1]=t;
    t=x,x=fa[x];        
  }
}

void rev(int x)
{
  access(x),splay(x);
  lazy[x]^=1;  
}

void link(int x,int y)
{rev(x);fa[x]=y;}

void cut(int x,int y)
{rev(x),access(y),splay(y),ch[y][0]=fa[x]=0;}

int find(int x)
{
  while(fa[x])x=fa[x];
  return x;
}

int main()
{
  int n,m;  
  scanf("%d%d",&n,&m);
  char opr[10];int t1,t2;
  for(int i=1;i<=m;i++)
  {
    scanf("%s",opr);
    scanf("%d%d",&t1,&t2);
    if(opr[0]=='C')link(t1,t2);
    else if(opr[0]=='D')cut(t1,t2);
    else 
    {
      t1=find(t1),t2=find(t2);
      if(t1==t2)printf("Yes\n");
      else printf("No\n");     
    }
  }
  return 0;    
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值