乱搞 - LCT求LCA

神犇学弟说LCA要用LCT求,于是我就听他的话写了一个LCT~

Code: 

#include <bits/stdc++.h> 
#define N 500005   
#define lson t[x].ch[0] 
#define rson t[x].ch[1]   
#define setIO(s) freopen(s".in","r",stdin)  ,freopen(s".out","w",stdout)   
using namespace std; 
int edges;  
int sta[N],hd[N<<1],nex[N<<1],to[N<<1],dep[N];     
void add(int u,int v) 
{
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;   
}
struct Node 
{
    int ch[2],f,val,rev;       
}t[N];  
int isrt(int x) 
{
    return !(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x); 
}
int get(int x) 
{
    return t[t[x].f].ch[1]==x;  
}  
void mark(int x,int d) 
{ 
    if(!x) return;  
    t[x].val=d;   
}
void markrev(int x) 
{
    if(!x) return;  
    t[x].rev^=1,swap(lson,rson);    
}
void pushdown(int x) 
{
    if(t[x].val) 
    {
        if(lson) mark(lson, t[x].val); 
        if(rson) mark(rson, t[x].val);    
    }
}   
void rotate(int x) 
{
    int old=t[x].f,fold=t[old].f,which=get(x); 
    if(!isrt(old)) t[fold].ch[t[fold].ch[1]==old]=x; 
    t[old].ch[which]=t[x].ch[which^1],t[t[old].ch[which]].f=old;  
    t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold;    
}
void splay(int x) 
{
    int v=0,u=x,fa; 
    for(sta[++v]=u;!isrt(u);u=t[u].f) sta[++v]=t[u].f;  
    for(;v;--v) pushdown(sta[v]);   
    for(u=t[u].f;(fa=t[x].f)!=u;rotate(x)) 
        if(t[fa].f!=u) 
            rotate(get(fa)==get(x)?fa:x);    
}
void Access(int x,int tt) 
{
    for(int y=0;x;y=x,x=t[x].f) 
    { 
        splay(x);                       
        rson=y;    
        t[x].val=tt;   
    }
}
int Access2(int x,int tt) 
{
    int id=0;   
    for(int y=0;x;y=x,x=t[x].f) 
    {
        splay(x);  
        if((!id&&t[x].val==tt))  id=x; 
        rson=y;   
    }
    return id;   
}   
void dfs(int u,int ff) 
{  
    t[u].f=ff;    
    dep[u]=dep[ff]+1;   
    for(int i=hd[u];i;i=nex[i]) 
        if(to[i]!=ff) dfs(to[i],u); 
}
int main() 
{ 
    // setIO("input"); 
    int n,m,s,i,j; 
    scanf("%d%d%d",&n,&m,&s);   
    for(i=1;i<n;++i) 
    {
        int a,b; 
        scanf("%d%d",&a,&b), add(a,b), add(b,a);           
    }   
    dfs(s,0);             
    for(i=1;i<=m;++i) 
    {
        int a,b; 
        scanf("%d%d",&a,&b);              
        Access(a,i);       
        printf("%d\n",Access2(b,i));  
    }  
    return 0; 
}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值