题目描述

小w喜欢打牌,某天小w与dogenya在一起玩扑克牌,这种扑克牌的面值都在1到n,原本扑克牌只有一面,而小w手中的扑克牌是双面的魔术扑克(正反两面均有数字,可以随时进行切换),小w这个人就准备用它来出老千作弊。小w想要打出一些顺子,我们定义打出一个l到r的顺子需要面值为从l到r的卡牌各一张。小w想问问你,他能否利用手中的魔术卡牌打出这些顺子呢?

输入描述:

首先输入一行2个正整数n,k,表示牌面为1~n,小w手中有k张魔术扑克牌。
  然后输入k行,每行两个数字,表示卡牌的正面和反面的面值。
  接下来输入一行一个正整数q,表示q组查询,然后每组占一行查询输入两个整数l,r。表示查询小w能否打出这么一个l到r的顺子。

输出描述:

对于输出"Yes"表示可以,"No"表示不可以。(不含引号)
  每个查询都是独立的,查询之间互不影响。
示例1
输入
  5 3
  1 2
  2 3
  4 4
  3
  1 2
  2 4
  1 4
输出
  Yes
  Yes
  No
说明
  对于顺子1~2,可以选择第一张卡牌作为'1'使用,选择第二张卡牌作为'2'使用。
  对于顺子2~4,可以选择第一张卡牌作为'2'使用,选择第二张卡牌作为'3'使用,选择第三张卡牌作为'4'使用。
  对于顺子1~4,由于牌的数目都不够,显然无法打出。
示例2
输入
  4 3
  1 1
  2 2
  4 4
  3
  1 2
  1 4
  4 4
输出
  Yes
  No
  Yes

分析

一开始想用dp,贪心,二分图之类的始终没想出来,后来强行逼自己往图论方面想才想到了解法

对于任意一张卡片我们可以把它看成一条边,将两个值连起来,而选择哪个值相当于给这条边定向

就拿样例1举例子,样例1的图如下

每张牌选哪个值,对应的那条边就指向哪个值

比如现在我们要凑出顺子[2,4],显然1不在顺子里,2在顺子里,那么连接1,2的边肯定指向2

那么结果如图

进而我们得出一个结论,在同一个联通块里面的数值,假设连通块大小为n,如果这个连通块是一棵树,那么连通块里面最多能取n-1个点(只有n-1条边)。

而且我们可以决定这n-1个点分别是哪些(只要找到不取的点,将它周围的边都指向其它节点,依次推下去即可

如果这个联通块中存在环,那么这个连通块中的所有点都可以取,如图

那么对于每棵树,我们求出它最小节点和最大节点,如果询问区间同时包含了最小节点和最大节点,就相当于包含了这棵树,

这个时候因为肯定有1个点取不到,所以肯定完成不了

所以对于每棵树求出它的最小节点,最大节点,这两个节点形成一段区间,包含这段区间的询问区间就无法完成

接下来就相当于要判断询问区间是否包含这些区间

如果一段区间[l,r]包含另一端区间[l1,r1],那么一定满足l<l1且r1<r。

在l1位置插入值r1,在l位置查询后缀最小值,如果该值小于r,那么一定存在左端点在l后面,右端点在r左边的区间,即被包含的区间

这个可以用数组维护,也可以O(n)扫过去预处理。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
int n,k,Q,mn[maxn],mx[maxn],bit[maxn],ori[maxn],vis[maxn],cnt[maxn][];
int find(int x){return !ori[x]?x:ori[x]=find(ori[x]);}
void add(int x,int k){for(;x;x-=(x&-x))bit[x]=min(bit[x],k);}
int que(int x){int ret=bit[];for(;x<=n;x+=(x&-x))ret=min(ret,bit[x]);return ret;}
int main()
{
scanf("%d%d",&n,&k);for(int i=;i<=n;i++)cnt[i][]=;
for(int i=,s1,s2;i<=k;i++)
{
scanf("%d%d",&s1,&s2);
s1=find(s1);s2=find(s2);
if(s1==s2){cnt[s1=s2][]++;continue;}
cnt[s1][]+=cnt[s2][];cnt[s1][]+=cnt[s2][]+;ori[s2]=s1;
}
for(int i=,s;i<=n;i++)if(!vis[s=find(i)])vis[s]=,mx[s]=i,mn[s]=i;else mx[s]=i;
memset(vis,,sizeof vis);memset(bit,0x3f,sizeof bit);
for(int i=,s;i<=n;i++)if(!vis[s=find(i)]){vis[s]=;if(cnt[s][]>cnt[s][])add(mn[s],mx[s]);}
scanf("%d",&Q);
for(int i=,l,r;i<=Q;i++)
{
scanf("%d%d",&l,&r);
if(r>=que(l))puts("No");else puts("Yes");
}
}

【牛客】小w的魔术扑克 (并查集?? 树状数组)的更多相关文章

  1. 牛客练习赛33 D tokitsukaze and Inverse Number (树状数组求逆序对,结论)

    链接:https://ac.nowcoder.com/acm/contest/308/D 来源:牛客网 tokitsukaze and Inverse Number 时间限制:C/C++ 1秒,其他语 ...

  2. Distance(2019年牛客多校第八场D题+CDQ+树状数组)

    题目链接 传送门 思路 这个题在\(BZOJ\)上有个二维平面的版本(\(BZOJ2716\)天使玩偶),不过是权限题因此就不附带链接了,我也只是在算法进阶指南上看到过,那个题的写法是\(CDQ\), ...

  3. 2019牛客多校第七场 F Energy stones 树状数组+算贡献转化模拟

    Energy stones 题意 有n块石头,每块有初始能量E[i],每秒石头会增长能量L[i],石头的能量上限是C[i],现有m次时刻,每次会把[s[i],t[i]]的石头的能量吸干,问最后得到了多 ...

  4. 计蒜客D2T2 蒜头君的排序(动态维护树状数组)

    蒜头君的排序(sort) 2000ms 262144K 蒜头君是一个爱思考的好孩子,这一天他学习了冒泡排序,于是他就想,把一个乱序排列通过冒泡排序排至升序需要多少次交换,这当然难不倒他,于是他想来点刺 ...

  5. Day1T3小w的魔术扑克——图论

    为什么不搞\(T2\)??? 因为我太菜了,那题我是真的搞不出来 题目描述 链接:https://ac.nowcoder.com/acm/contest/1100/C 来源:牛客网 小\(w\)喜欢打 ...

  6. [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)

    显然有决策单调性,但由于逆序对不容易计算,考虑分治DP. solve(k,x,y,l,r)表示当前需要选k段,待更新的位置为[l,r],这些位置的可能决策点区间为[x,y].暴力计算出(l+r)/2的 ...

  7. 牛客-小w的a=b问题

    题目传送门 sol1:老实做,预处理出所有2到1e5的素数,对所有数进行分解质因数,然后对比因子个数.感觉有点卡常,用了快读然后多次优化之后才过的,map也用上了. 素数筛,快速分解质因数 #incl ...

  8. 求序列A中每个数的左边比它小的数的个数(树状数组)

    给定一个有N个正整数的序列A(N<=10^5,A[i]<=10^5),对序列中的每一个数,求出序列中它左边比它小的数的个数. 思路:树状数组的经典应用(裸题) #include <i ...

  9. AcWing:244. 谜一样的牛(树状数组 + 二分)

    有n头奶牛,已知它们的身高为 1~n 且各不相同,但不知道每头奶牛的具体身高. 现在这n头奶牛站成一列,已知第i头牛前面有AiAi头牛比它低,求每头奶牛的身高. 输入格式 第1行:输入整数n. 第2. ...

随机推荐

  1. Matlab适配器模式

    适配器模式是连接两个不兼容接口的桥梁,主要分为三种:类适配器.对象适配器以及接口适配器,本文根据https://blog.csdn.net/u012359453/article/details/791 ...

  2. css,对包含有子元素的元素进行flex后,会影响原有的布局。如何后续处理

    对包含有子元素的元素进行flex后,会影响原有的布局. 例如设置两个div,第一个div包含一个img(图片),第二个div包含多个p元素(对前面的img的说明).如下图 1:当对着两个两个div进行 ...

  3. 已知IP地址算子网掩码

    子网掩码计算方法有两种: 方法一:利用子网数来计算: 1.首先,将子网数目从十进制数转化为二进制数: 2.接着,统计得到的二进制数的位数,设为N: 3.最后,先求出此IP地址对应的地址类别的子网掩码. ...

  4. HTTP协议学习总结

    一个web应用程序,往往是通过http协议进行前后端通信的.而作为一个web工程师,掌握HTTP协议因此也是Web开发必备的一项技能了,尤其是在工作了一定年限之后,更是深感该知识点的重要性.因此,将以 ...

  5. Linux Samba服务器的安装

    Samba最大的功能就是可以用于Linux与windows系统直接的文件共享和打印共享,也可以用于Linux与Linux之间的资源共享 安装 # yum install samba samba-cli ...

  6. Linux--基本目录

    特点 系统版本:CentOS 6.5 Linux目录:一切从根开始 Linux下面的设备(磁盘)不挂载的话没有办法使用,使用设备必须有一个入口,挂载点实质就是一个目录. 目录结构及含义 目录 说明 b ...

  7. Java开发环境之Eclipse

    查看更多Java开发环境配置,请点击<Java开发环境配置大全> 拾壹章:Eclipse安装教程 1)去官网下载安装包 http://www.eclipse.org/downloads/ ...

  8. Pthon魔术方法(Magic Methods)-实例化

    Pthon魔术方法(Magic Methods)-实例化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.实例化一个对象 __new__: 该方法需要返回一个值,如果该值不是cl ...

  9. Eclipse经常出现未响应问题

    修改eclipse.ini文件 -startupplugins/org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar--launcher.libr ...

  10. Chrome浏览器内部协议Chrome://收集

    Chromium 采用 Chrome:// 协议开头的形式, 规定了一系列的内部协议, 有的用来显示数据, 有的用来实现一些功能, 但对普通用户进行了屏蔽.在Chrome浏览器地址栏直接访问就好了! ...