BZOJ2049 SDOI2008 洞穴勘测 cave

本题是一个动态树的模板题、

link-cut-tree的论文可以百度文库中找、

 

Code:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <queue>
 
#define ps system("pause")
#define message printf("*\n")
#define pb push_back
#define X first
#define Y second
#define PII pair<int,int>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>=c;a++)
 
typedef long long ll;
 
using namespace std;
 
struct node{
    int son[2],fa,pf;
    bool isrev;
}tr[500010];
 
int n,m,x,y;
char cmd[20];
 
void update(int x){
    if  (tr[x].isrev && x){
        tr[x].isrev=0;
        tr[tr[x].son[0]].isrev=!tr[tr[x].son[0]].isrev;
        tr[tr[x].son[1]].isrev=!tr[tr[x].son[1]].isrev;
        swap(tr[x].son[0],tr[x].son[1]);
    }
}
 
void zig(int now){  
    int F=tr[now].fa;
    tr[now].pf=tr[F].pf;tr[F].pf=0;
    tr[F].son[1]=tr[now].son[0];
    if  (tr[now].son[0])    tr[tr[now].son[0]].fa=F;
    tr[now].fa=tr[F].fa;
    if  (tr[F].fa)
        if  (tr[tr[F].fa].son[0]==F)    tr[tr[F].fa].son[0]=now;
        else    tr[tr[F].fa].son[1]=now;
    tr[F].fa=now;
    tr[now].son[0]=F;
}
  
void zag(int now){
    int F=tr[now].fa;
    tr[now].pf=tr[F].pf;tr[F].pf=0;
    tr[F].son[0]=tr[now].son[1];
    if  (tr[now].son[1])    tr[tr[now].son[1]].fa=F;
    tr[now].fa=tr[F].fa;
    if  (tr[F].fa)
        if  (tr[tr[F].fa].son[0]==F)    tr[tr[F].fa].son[0]=now;
        else    tr[tr[F].fa].son[1]=now;
    tr[F].fa=now;
    tr[now].son[1]=F;
}
  
void splay(int now){
    if  (!now) return  ;
    while   (tr[now].fa){
        update(tr[now].fa);
        update(tr[tr[now].fa].son[0]);
        update(tr[tr[now].fa].son[1]);
        if  (tr[tr[now].fa].son[0]==now)   zag(now);else   zig(now);
    }
}
 
void access(int x){
    splay(x);update(x);
    tr[tr[x].son[1]].pf=x;
    tr[tr[x].son[1]].fa=0;
    tr[x].son[1]=0;
    for (int u=tr[x].pf;u;u=tr[x].pf){
        splay(u);update(u);
        tr[tr[u].son[1]].fa=0;
        tr[tr[u].son[1]].pf=u;
        tr[u].son[1]=x;
        tr[x].fa=u;
        tr[x].pf=0;
        x=u;
    }
    splay(x);
}
 
int findroot(int x){
    access(x);splay(x);update(x);
    while   (tr[x].son[0])  x=tr[x].son[0];
    return  x;
}
 
void reverse(int x){
    access(x);splay(x);
    tr[x].isrev=!tr[x].isrev;
    update(x);
}
 
void makenew(int x){
    tr[x].fa=tr[x].pf=tr[x].son[0]=tr[x].son[1]=tr[x].isrev=0;
}
 
int main(){
    //freopen("cave.in","r",stdin);
    scanf("%d%d\n",&n,&m);
    rep(i,1,n)  makenew(i);
    rep(i,1,m){
        scanf("%s %d %d\n",cmd,&x,&y);
        //cout <<i <<":" <<cmd <<endl;
        switch  (cmd[0]){
            case    'C':
                reverse(x);splay(x);update(x);
                access(y);splay(y);update(y);
                tr[x].son[0]=y;tr[y].fa=x;
                break;
            case    'D':
                reverse(x);
                access(y);splay(y);update(y);
                tr[tr[y].son[0]].fa=0;tr[y].son[0]=0;
                break;
            case    'Q':
                if  (findroot(x)==findroot(y))  puts("Yes");
                else    puts("No");
                break;
        }
    }
}

  

 

转载于:https://www.cnblogs.com/JS-Shining/archive/2013/05/23/3095795.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值