[SDOI2008]洞穴勘测

SOL: LCT维护联通性,当然,启发式合并并查集可能会更好写。

#include<bits/stdc++.h>
#define N 200007
int rev[N],ch[N][2],f[N],q[N],top;
using namespace std;
inline void push_down(int x) {
    if (rev[x]) {
        rev[ch[x][0]]^=1; rev[ch[x][1]]^=1; rev[x]=0;
        swap(ch[x][0],ch[x][1]);
    }
}
inline bool rt(int x){
    return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;
}
inline void ro(int x){
    int y=f[x],z=f[y],kind=(ch[y][0]==x);
    if (!rt(y)) ch[z][ch[z][1]==y]=x;
    f[ch[x][kind]]=y; f[y]=x; f[x]=z;
    ch[y][kind^1]=ch[x][kind]; ch[x][kind]=y;
}
//inline void splay(int x){
inline void splay(int x) {
    q[top=1]=x;
    for (int i=x;!rt(i);i=f[i]) q[++top]=f[i];
    while (top) push_down(q[top--]);
    while (!rt(x)) {
        int y=f[x],z=f[y];
        if (!rt(y))
        {
           if (ch[y][0]==x^ch[z][0]==y) ro(x);
           else ro(y);
        }
        ro(x);
    }
//    push_up(x);
}
inline void access(int x) {
    for (int t=0;x;t=x,x=f[x]) splay(x),ch[x][1]=t;
}
inline void make_rt(int x) {
    access(x); splay(x); rev[x]^=1;
}
inline void link(int x,int y){
    make_rt(x); f[x]=y;
}
inline int find(int x){
    access(x); splay(x); while (ch[x][0]) push_down(x),x=ch[x][0];
    return x;
}
inline void cut(int x,int y){
    make_rt(x);
    if (find(y)==x&&f[x]==y&&!ch[x][1])  f[x]=ch[y][0]=0;
}
int n,m,x,y;
char as[19];
signed main () {
//    freopen("a.in","r",stdin);
    scanf("%d%d",&n,&m);
    while (m--) {
        scanf("%s",as);
        scanf("%d%d",&x,&y);
        if (as[0]==‘Q‘) {
            printf("%s\n",(find(x)^find(y))?"No":"Yes");
        } else if (as[0]==‘C‘) {
            if (find(x)^find(y))
             link(x,y);
        } else {
            if (find(x)==find(y)) cut(x,y);
        }
    }
}

原文地址:https://www.cnblogs.com/rrsb/p/8885895.html

时间: 2024-11-10 14:27:53

[SDOI2008]洞穴勘测的相关文章

P2147 [SDOI2008]洞穴勘测

题目 P2147 [SDOI2008]洞穴勘测 做法 说实话如果你在看这篇题解的话应该也没有人劝你回去打模板吧 My complete code #include<cstdio> #include<cstring> #include<iostream> #include<string> using namespace std; typedef int LL; const LL maxn=1e6; inline LL Read(){ LL x(0),f(1);

BZOJ2049:[SDOI2008]洞穴勘测——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=2049 https://www.luogu.org/problemnew/show/P2147 辉辉热衷于洞穴勘测. 某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为

BZOJ2049 SDOI2008 洞穴勘测 LCT

题意:给定一棵树,维护:1.删除一条边  2.添加一条边  3.询问u和v是否连通 题解:LCT维护连通性 #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int MAXN=10000+2; typedef struct NODE{ NODE *ch

BZOJ-2049 [Sdoi2008]洞穴勘测

LCT模版题.... #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <cctype> #include <cmath> #define rep(i, l, r) for(int i=l; i<=r; i++) #define clr(x, c) mems

【题解】Luogu P2147 [SDOI2008]洞穴勘测

原题传送门 这题用Link-Cut-Tree解决,Link-Cut-Tree详解 我不太会踩爆Link-Cut-Tree的并查集做法qaq 我们用Link-Cut-Tree维护连通性(十分无脑) Connect操作:把u,v两个点连起来 Destroy操作:把u,v两个点分开来 Query操作:判断在这个森林里u的根和v的根是否相等 #include <bits/stdc++.h> #define N 10005 using namespace std; inline int read() {

[LuoguP2147] [SDOI2008]洞穴勘测 (LCT维护连通性)

题面 传送门:https://www.luogu.org/problemnew/show/P2147 Solution 这题...... 我们可以发现题目要求我们维护一个动态森林,而且只查询连通性.... 显然LCT模板题啊,关于LCT玩法,可以猛戳这里学习 Code #include<iostream> #include<cstdio> #include<vector> using namespace std; long long read() { long long

BZOJ 2049([Sdoi2008]Cave 洞穴勘测-LCT)[Template:LCT]

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 4809  Solved: 2141 [Submit][Status][Discuss] Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接

BZOJ 题目2049: [Sdoi2008]Cave 洞穴勘测(link cut tree)

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 4698  Solved: 2107 [Submit][Status][Discuss] Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接

BZOJ 2049: [Sdoi2008]Cave 洞穴勘测

二次联通门 : BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 其实指针也不是很慢 我的指针代码能吊打70%的数组 及80%的指针.... /* BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 LCT 连边 删边 查询是否在同一树中时, 只需要一直向上跳 看看树根是否相同就好了 */ #include <cstdio> #include <cstdlib> #include <iostream> #define Max 400009 int