acwing 239. 奇偶游戏 并查集
地址 https://www.acwing.com/problem/content/241/
小A和小B在玩一个游戏。
首先,小A写了一个由0和1组成的序列S,长度为N。
然后,小B向小A提出了M个问题。
在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个1。
机智的小B发现小A有可能在撒谎。
例如,小A曾经回答过 S[1~3] 中有奇数个1, S[4~6] 中有偶数个1,现在又回答 S[1~6] 中有偶数个1,显然这是自相矛盾的。
请你帮助小B检查这M个答案,并指出在至少多少个回答之后可以确定小A一定在撒谎。
即求出一个最小的k,使得01序列S满足第1~k个回答,但不满足第1~k+1个回答。
输入格式
第一行包含一个整数N,表示01序列长度。
第二行包含一个整数M,表示问题数量。
接下来M行,每行包含一组问答:两个整数l和r,以及回答“even”或“odd”,用以描述S[l~r] 中有奇数个1还是偶数个1。
输出格式
输出一个整数k,表示01序列满足第1~k个回答,但不满足第1~k+1个回答,如果01序列满足所有回答,则输出问题总数量。
数据范围
N≤10^9,M≤
输入样例: even
odd
even
even
odd
输出样例:
解答1:
带权并查集
本题目有两个难点
1 数据范围过大 有 10^9
2 询问的内容如何转化到并查集
问题1 的解决办法是 使用离散化 将不同的数据映射到1 2 3 4。。。,由于只有10000次 询问,每次询问提供两个数据 所以只要提供10000*2的数据范围即可
问题2 的解决办法是 前缀和 如果提供 l和r的范围内1有奇数个还是偶数个 也就是计算 前缀和 sum[r] - sum[l-1]
另由于有偶数减偶数 奇数减奇数 都是偶数 只有两者不同类型分别是奇数偶数中的一种 才会出现最后的差是奇数
那么并查集其实也就是前缀和中每个元素的奇偶性
增加带权数组 所有的前缀和元素都会合并到一个祖先中,d[x]带权数组会记录x元素是否与根是同样的奇偶性
当得到新的询问时候 如果两个元素已经合并在同一个祖先下,那么就可以根据他们与祖先的异同得到他们的异同,再来判断他们与输入的异同是否一致 如果不一致就是发生矛盾,返回即可
代码如下
#include <iostream>
#include <string>
#include <unordered_map> using namespace std; const int MAX_M = ; int N, M;
int n, m; int fa[MAX_M];
int d[MAX_M]; int idx = ; unordered_map<int, int> S; //离散化
int get(int x) {
if (S.count(x) == ) S[x] = ++idx;
return S[x];
} void init()
{
for (int i = ; i < MAX_M; i++) {
fa[i] = i;
}
} int find(int x) {
if (fa[x] != x) {
int root = find(fa[x]);
d[x] += d[fa[x]]%;
fa[x] = root;
} return fa[x];
} int main()
{ cin >> n >> m;
int res = m;
init();
for (int i = ; i <= m; i++) {
int a, b; string s;
cin >> a >> b >> s;
a = get(a - ); b = get(b);
int pa = find(a), pb = find(b); if (pa == pb) {
//查看两者是否符合之前的信息
if (s == "even")
{
//两者奇偶性相同
if( (d[a] + d[b]) % != ){
//有矛盾
res = i - ;
break;
}
}
else if (s == "odd") {
//两者奇偶性不同
if ((d[a] + d[b]) % != ) {
//有矛盾
res = i - ;
break;
}
}
else {
cout << s << endl;
cout << "error" << endl;
break;
}
}
else {
//pa != pb
//合并
fa[pa] = pb;
int add = ;
if (s == "odd") add = ;
d[pa] = (d[a] + d[b] + add)%;
} }
cout << res << endl; return ;
}
带权并查集
解法2 并查集扩展域
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map> using namespace std; const int MAX_N = *;
const int Base = MAX_N / ; unordered_map<int, int> S;
int n, m; int p[MAX_N]; int idx = ;
//离散化
int get(int x) {
if (S.count(x) == ) S[x] = ++idx;
return S[x];
} int find(int x)
{
if (x != p[x]) p[x] = find(p[x]); return p[x];
} int main()
{
cin >> n >> m; int res = m;
for (int i = ; i < MAX_N; i++) p[i] = i; for (int i = ; i <= m; i++) {
int a, b; string s;
cin >> a >> b >> s;
a = get(a - ); b = get(b); if (s == "even") {
//相同
if (find(a + Base) == find(b)) {
res = i - ;
break;
}
p[find(a)] = find(b);
p[find(a + Base)] = p[find(b + Base)];
}
else {
if (find(a) == find(b)) {
res = i - ;
break;
}
p[find(a+Base)] = find(b);
p[find(a )] = p[find(b + Base)]; } }
cout << res << endl; return ;
}
扩展域
acwing 239. 奇偶游戏 并查集的更多相关文章
- AcWing 239.奇偶游戏 (带权并查集/种类并查集)
题意:你和朋友玩游戏,有个一\(01\)序列,你每次给出一个区间,朋友会回答这个区间中的\(1\)的个数是奇数还是偶数,但是你亲爱的朋友可能在撒谎,问在哪个询问你能确定你的朋友在撒谎,输出回合数. 题 ...
- acwing 1250. 格子游戏 并查集
地址 https://www.acwing.com/problem/content/1252/ Alice和Bob玩了一个古老的游戏:首先画一个 n×nn×n 的点阵(下图 n=3n=3 ). 接着, ...
- AcWing 239. 奇偶游戏
小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...
- AcWing:239. 奇偶游戏(前缀和 + 离散化 + 带权并查集 + 异或性质 or 扩展域并查集 + 离散化)
小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...
- BZOJ 1854: [Scoi2010]游戏 并查集
1854: [Scoi2010]游戏 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 2672 Solved: 958[Submit][Status][ ...
- 1854: [Scoi2010]游戏[并查集]
1854: [Scoi2010]游戏 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4938 Solved: 1948[Submit][Status] ...
- 洛谷 P1640 SCOI2010 连续攻击游戏 并查集
题目描述 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备 ...
- bzoj 1854: [Scoi2010]游戏 (并查集||二分图最大匹配)
链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1854 写法1: 二分图最大匹配 思路: 将武器的属性对武器编号建边,因为只有10000种 ...
- 【bzoj1854】[Scoi2010]游戏 - 并查集
lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备最多只能使 ...
随机推荐
- Azkaban3.x
Azkaban3.x安装部署 官方文档地址 三种模式 solo-server模式:exec进程和web进程为同一个进程,存放元数据的数据库为H2 two-server模式:与之前的单机版本类似,exe ...
- 为什么不喜欢在 QQ 群里回答问题?
为什么不喜欢在 QQ 群里回答问题? 没有主题,主题随时都在变. 回答后无法备份,当然自己有心可以总结一下. 实时性要求太强,可能回答但是突然有事离开,再回头看已经是 几十条的留言. QQ 群用来闲聊 ...
- MySQL常用函数大全讲解
MySQL数据库中提供了很丰富的函数.MySQL函数包括数学函数.字符串函数.日期和时间函数.条件判断函数.系统信息函数.加密函数.格式化函数等.通过这些函数,可以简化用户的操作.例如,字符串连接函数 ...
- mybatis-generator1.3.6的使用
下载地址: http://blog.mybatis.org/2017/12/mybatis-generator-version-136-released.html 参考了 http://blog.cs ...
- 1x1卷积
你可能会想为什么有人会用1x1卷积,因为它关注的不是一块像素,而是一个像素,图1 图1 我们看看传统的卷积,它基本上是运行在一个小块图像上的小分类器,但仅仅是个线性分类器.图2 图2 如果你在中间加一 ...
- 读取hive的表结构,生成带comment的视图建表语句
### 读取hive的表结构,生成带comment的视图建表语句 # 读取配置文件中的表并进行遍历 grep -v '^#' tablesFile|while read tableName do st ...
- js 过滤富文本标签数据
var str = '<p><code>uni-app</code> 完整支持 <code>Vue</code> 实例的生命周期,同时还新增 ...
- fastclick使用与 fastclick ios11.3相关bug原因(ios输入框点击变得不灵敏,ios input失焦后,页面上移,点击不了)
FastClick 移动设备上的浏览器默认会在用户点击屏幕大约延迟300毫秒后才会触发点击事件,这是为了检查用户是否在做双击.为了能够立即响应用户的点击事件,就有了FastClick. 安装fastc ...
- java Jre和Jdk的区别?
JRE:(Java Runtime Environment),java运行环境.包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等,如果想要运行一个开 ...
- 快速理解bootstrap,bagging,boosting,gradient boost-三个概念
1 booststraping:意思是依靠你自己的资源,称为自助法,它是一种有放回的抽样方法,它是非参数统计中一种重要的估计统计量方差进而进行区间估计的统计方法. 其核心思想和基本步骤如下: (1 ...