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]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备最多只能使 ...
随机推荐
- 【NS2】NS2 教學手冊(转载)
之前做毕设的时候搜索NS2的相关资料,发现这个里面涵盖很广,特此收藏,感谢原作者的辛勤劳作. NS2 教學手冊 ( NS2 Learning Guide) [快速連結區] My works 中文影音 ...
- 三角形数且是完全平方数 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 E.Half-consecutive Numbers
三角形数:an=n*(n+1)/2; 完全平方数:bn=c^2; 既是三角形数又是完全平方数:An=6*A(n-1)-A(n-2)+2; A[23]={ 0, 1, 8, 49, 288, 1681, ...
- F4NNIU 的 KiCad EDA 技巧 (2019-05-09 更新)
F4NNIU 的 KiCad EDA 技巧 已经慢慢切换到 KiCadEDA 上来画板,优点很多. 开源: 自动推挤: 无限的元件库: 强大的 3D 显示: 这里整理一下个人使用的技巧: 原理图 Ee ...
- 云上快速搭建Serverless AI实验室
Serverless Kubernetes和ACK虚拟节点都已基于ECI提供GPU容器实例功能,让用户在云上低成本快速搭建serverless AI实验室,用户无需维护服务器和GPU基础运行环境,极大 ...
- P2P四红线
P2P四红线 刘张君指出,P2P网络借贷平台是一种新兴金融业态,在鼓励其创新发展的同时,要记住四点:一是要明确这个平台的中介性质,二是要明确平台本身不得提供担保,三是不得将归集资金搞资金池,四是不得非 ...
- 洛谷P1510 精卫填海
//01背包 求背包内物品价值超过某一定值时的最小体积 #include<bits/stdc++.h> using namespace std; ; ; int n,v_tot,w_tot ...
- Python基础:25文件
一:文件对象 文件对象不仅可以用来访问普通的磁盘文件, 而且也可以访问任何其它类型抽象层面上的"文件". 一旦设置了合适的"钩子", 你就可以访问具有文件类型接 ...
- 添加ODBC数据源
添加ODBC数据源
- @noi.ac - 493@ trade
目录 @description@ @solution@ @part - 1@ @part - 2@ @part - 3@ @part - 4@ @accepted code@ @details@ @d ...
- MyBatis-使用XML或注解的简单实例
一.导入jar包 <dependency> <groupId>junit</groupId> <artifactId>junit</artifac ...