洛谷P2147[SDOI2008]洞穴勘测(lct)

news/2024/7/3 9:02:33

题目描述

辉辉热衷于洞穴勘测。

某天,他按照地图来到了一片被标记为JSZX的洞穴群地区。经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴。假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径。 洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通道,有时这条通道又会因为某种稀奇古怪的原因被毁。

辉辉有一台监测仪器可以实时将通道的每一次改变状况在辉辉手边的终端机上显示:

如果监测到洞穴u和洞穴v之间出现了一条通道,终端机上会显示一条指令 Connect u v

如果监测到洞穴u和洞穴v之间的通道被毁,终端机上会显示一条指令 Destroy u v

经过长期的艰苦卓绝的手工推算,辉辉发现一个奇怪的现象:无论通道怎么改变,任意时刻任意两个洞穴之间至多只有一条路径。

因而,辉辉坚信这是由于某种本质规律的支配导致的。因而,辉辉更加夜以继日地坚守在终端机之前,试图通过通道的改变情况来研究这条本质规律。 然而,终于有一天,辉辉在堆积成山的演算纸中崩溃了……他把终端机往地面一砸(终端机也足够坚固无法破坏),转而求助于你,说道:“你老兄把这程序写写吧”。

辉辉希望能随时通过终端机发出指令 Query u v,向监测仪询问此时洞穴u和洞穴v是否连通。现在你要为他编写程序回答每一次询问。 已知在第一条指令显示之前,JSZX洞穴群中没有任何通道存在。

输入输出格式

输入格式:

 

第一行为两个正整数n和m,分别表示洞穴的个数和终端机上出现过的指令的个数。 以下m行,依次表示终端机上出现的各条指令。每行开头是一个表示指令种类的字符串s("Connect”、”Destroy”或者”Query”,区分大小写),之后有两个整数u和v (1≤u, v≤n且u≠v) 分别表示两个洞穴的编号。

 

输出格式:

 

对每个Query指令,输出洞穴u和洞穴v是否互相连通:是输出”Yes”,否则输出”No”。(不含双引号)

 

输入输出样例

输入样例#1: 复制
200 5
Query 123 127
Connect 123 127
Query 123 127
Destroy 127 123
Query 123 127
输出样例#1: 复制
No
Yes
No
输入样例#2: 复制
3 5
Connect 1 2
Connect 3 1
Query 2 3
Destroy 1 3
Query 2 3
输出样例#2: 复制
Yes
No

说明

数据说明

10%的数据满足n≤1000, m≤20000

20%的数据满足n≤2000, m≤40000

30%的数据满足n≤3000, m≤60000

40%的数据满足n≤4000, m≤80000

50%的数据满足n≤5000, m≤100000

60%的数据满足n≤6000, m≤120000

70%的数据满足n≤7000, m≤140000

80%的数据满足n≤8000, m≤160000

90%的数据满足n≤9000, m≤180000

100%的数据满足n≤10000, m≤200000

保证所有Destroy指令将摧毁的是一条存在的通道

本题输入、输出规模比较大,建议c\c++选手使用scanf和printf进行I\O操作以免超时

 

题解:大概就是写一颗支持link和cut的lct,然后判断find_root(y)等不等于x就可以了

 

代码如下:

#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100010
#define lson ch[x][0]
#define rson ch[x][1]
using namespace std;

int tag[N],f[N],sz[N],ch[N][2];

int not_root(int now)
{
    int x=f[now];
    return lson==now||rson==now;
}

int rev(int x)
{
    swap(lson,rson);
    tag[x]^=1;
}

int push_down(int x)
{
    if(tag[x])
    {
        rev(lson);
        rev(rson);
        tag[x]^=1;
    }
}

int rotate(int x)
{
    int y=f[x],z=f[y],kd=ch[y][1]==x,xs=ch[x][!kd];
    if(not_root(y))
    {
        ch[z][ch[z][1]==y]=x;
    }
    ch[x][!kd]=y;
    ch[y][kd]=xs;
    if(xs) f[xs]=y;
    f[y]=x;
    f[x]=z;
}

int push_all(int x)
{
    if(not_root(x))
    {
        push_all(f[x]);
    }
    push_down(x);
}

int splay(int x)
{
    int y,z;
    push_all(x);
    while(not_root(x))
    {
        y=f[x],z=f[y];
        if(not_root(y))
        {
            (ch[y][0]==x)^(ch[z][0]==y)?rotate(x):rotate(y);
        }
        rotate(x);
    }
}

int access(int x)
{
    for(int y=0;x;y=x,x=f[x])
    {
        splay(x);
        rson=y;
    }
}

int make_root(int x)
{
    access(x);splay(x);
    rev(x);
}

int find_root(int x)
{
    access(x);
    splay(x);
    while(lson)
    {
        push_down(x);
        x=lson;
    }
    return x;
}

int link(int x,int y)
{
    make_root(x);
    if(find_root(y)==x) return 0;
    f[x]=y;
    return 1;
}

int cut(int x,int y)
{
    make_root(x);
    if(find_root(y)!=x||f[x]!=y||rson) return 0;
    f[x]=ch[y][0]=0;
    return 1;
}

int n,m;
char c[20];
int from,to;

int main()
{
    scanf("%d %d\n",&n,&m);
    while(m--)
    {
        scanf("%s %d %d",c,&from,&to);
        if(c[0]=='Q')
        {
            make_root(from);
            if(find_root(to)==from) puts("Yes");
            else puts("No");
        }
        if(c[0]=='C')
        {
            link(from,to);
        }
        if(c[0]=='D')
        {
            cut(from,to);
        }
    }
}

 

转载于:https://www.cnblogs.com/stxy-ferryman/p/9464896.html


http://www.niftyadmin.cn/n/3018945.html

相关文章

Flink - Table API 之 window (窗口)

窗口 时间语义&#xff0c;要配合窗口操作才能发挥作用在Table API 和 SQL 中&#xff0c;主要有两种窗口 Group Window(分组窗口) 根据时间或行计数间隔&#xff0c;将行聚合到有限的组(Group)中&#xff0c;并对每个组的数据执行一次聚合函数 Over Windows 针对每个输入…

lwip 网络接口结构体 netif

2019独角兽企业重金招聘Python工程师标准>>> 在lwIP中&#xff0c;是通过结构体netif来描述一个硬件网络接口的&#xff0c;在单网卡中&#xff0c;这个结构体只有一个&#xff0c;多网卡中可有何网卡数目相同的netif结构体&#xff0c;它们构成一个数据链。 /** Ge…

嵌入式linux学习笔记-- linux下inotify的使用(转载)

原文地址&#xff1a;http://www.cnblogs.com/jimmychange/p/3498862.html 有时候我们需要检测某个目录下文件或者子目录的改动状况&#xff0c;如添加、删除、以及更新等&#xff0c;Linux系统上提供了inotify来完成这个功能。inotify是在版本2.6.13的内核中首次出现&#xff…

微信接口测试

""用于向指定用户发送消息前提&#xff1a; 1. 申请账号 "appid": wx65d37317efb972e0, "secret": f59dc1e2f5e3641145a213027fb122cc, 2. 知道用户的微信ID othEL0hlOrdBIRLLXuX0BA8frGZE"""import …

嵌入式linux学习笔记---TCP立即发出 以及 TCP的keep alive

事情的起因是公司的产品的某一个功能存在的bug&#xff0c;所以就有了本次的探索。 需求&#xff1a; 产品在某一个端口上 定时的向外发送1440 字节的数据包&#xff0c;该数据包包含了产品当前的各种状态。 需求2 &#xff1a; 产品本身绑定一个本地的端口 接收来自外部的字符…

Flink Sort-Shuffle写简析

文章目录1、配置2、初始创建3、成员变量4、写shuffle文件4.1、获取SortBuffer4.2、追加数据4.3、buffer不足的处理4.4、buffer不足数据未读完5、关于排序5.1、segment申请5.2、writeIndex5.2.1、获取当前可用segment5.2.2、写入index到segment5.2.3、更新partition最后数据的索…

Flink Sort-Shuffle读简析

文章目录1、SortMergeResultPartition的创建使用2、PartitionedFileReader2.1、moveToNextReadableRegion2.2、readCurrentRegion2.3、hasRemaining3、读操作的调用4、数据返回4.1、读入缓存4.2、buffersRead读取1、SortMergeResultPartition的创建使用 首先是一个读过程的一个…

信息社会

消息 通知 公告(简报) 新闻(深度分析文章) 历史(沉淀形成知识) 各部门的信息系统 陕西省住房和城乡建设厅 陕西省建筑市场监管平台陕西省质量安全监管信息系统陕西省标准定额协同管理平台陕西省房地产市场监管信息系统陕西省城市园林绿化企业信息管理系统陕西省执业资格注册人员…