AcWing:239. 奇偶游戏(前缀和 + 离散化 + 带权并查集 + 异或性质 or 扩展域并查集 + 离散化)
小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≤109,M≤10000N≤109,M≤10000
输入样例:
10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
输出样例:
3
带权并查集:
题解:如果我们用sum数组表示序列S的前缀和,那么在每个回答中:
1、S[l ~ r] 有偶数个1,等价于 sum[l - 1] 与 sum[r] 奇偶性相同。
2、S[l ~ r] 有奇数个1,等价于 sum[l - 1] 与 sum[r] 奇偶性不同。
注意,我们在本题中不需要求sum数组,只要把它看成一个变量。
1、x1 与 x2 的奇偶性相同,x2 与 x3 的奇偶性也相同,那么 x1 与 x3 的奇偶性相同。
2、x1 与 x2 的奇偶性相同,x2 与 x3 的奇偶性不同,那么 x1 与 x3 的奇偶性不同。
3、x1 与 x2 的奇偶性不同,x2 与 x3 的奇偶性不同,那么 x1 与 x3 的奇偶性相同。
假设 d[x] 是 x ~ p 的奇偶性, d[y] 是 y ~ q 的奇偶性, d[p] 是 p ~ q 是奇偶性(其中x ~ p 和 y ~ q是两个不同的集合,p ~ q是两个集合的路径)。那么,ans = d[x] ^ d[y] ^ d[p],可以推出d[p] = d[x] ^ d[y] ^ ans(读者可以自己证明)。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector> using namespace std; const int maxn = 1e4+; struct node {
int l, r, ans;
}arr[maxn]; vector<int> v;
int f[maxn];
int d[maxn];
int n, m; int find(int x) {
return lower_bound(v.begin(), v.end(), x) - v.begin() + ;
} void init() {
v.clear();
for(int i = ; i <= m; i++) {
char str[];
scanf("%d %d %s", &arr[i].l, &arr[i].r, str);
arr[i].ans = (str[] == 'o') ? : ; //奇数为1,偶数为0
v.push_back(arr[i].l - );
v.push_back(arr[i].r);
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end()); //离散化
n = v.size();
for(int i = ; i <= n; i++) {
f[i] = i;
d[i] = ;
}
} int get(int x) {
if(x == f[x]) {
return f[x];
}
int root = get(f[x]);
d[x] ^= d[f[x]];
return f[x] = root;
} int main() {
scanf("%d %d", &n, &m);
init();
for(int i = ; i <= m; i++) {
int x = find(arr[i].l - );
int y = find(arr[i].r);
int fx = get(x);
int fy = get(y);
if(fx == fy) {
if((d[x] ^ d[y]) != arr[i].ans) { //与前面的回答相矛盾
printf("%d\n", i - );
return ;
}
} else {
f[fx] = fy;
d[fx] = d[x] ^ d[y] ^ arr[i].ans;
}
}
printf("%d\n", m);
return ;
}
扩展域并查集:
题解:同上,如果我们用sum数组表示序列S的前缀和,那么在每个回答中:
1、S[l ~ r] 有偶数个1,等价于 sum[l - 1] 与 sum[r] 奇偶性相同。
2、S[l ~ r] 有奇数个1,等价于 sum[l - 1] 与 sum[r] 奇偶性不同。
注意,我们在本题中不需要求sum数组,只要把它看成一个变量。
我们可以把变量x拆成两个节点xodd和xeven,其中xodd表示sum[x]是奇数,xeven表示sum[x]是偶数。我们那也可以把这两个节点称为x的“奇数域”和“偶数域”。
对于每个问题,设在离散化后l - 1和r的值分别是x和y,设ans表示该问题回答(0表示偶数个1,1表示奇数个1)
1、若ans = 0是,则合并xodd与yodd,xeven和yeven。这表示“x为奇数”和“y为奇数”可以互相推出,“x位偶数”和“y位偶数”可以互相推出。
2、若ans = 0是,则合并xodd与yeven,xeven和yodd。这表示“x为奇数”和“y为偶数”可以互相推出,“x位偶数”和“y位奇数”可以互相推出。
上述合并还维护了关系的传递性。若xodd和yodd在同一集合内,则两者的奇偶性相同。若xodd和yeven在同一集合内,则两者的奇偶性不同。
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm> using namespace std; const int maxn = 1e4+; struct node {
int l, r, ans;
}arr[maxn]; vector<int> v;
int f[maxn];
int n, m; void init() {
for(int i = ; i <= m; i++) {
char str[];
scanf("%d %d %s", &arr[i].l, &arr[i].r, str);
arr[i].ans = (str[] == 'o') ? : ; //奇数为1,偶数为0
v.push_back(arr[i].l - );
v.push_back(arr[i].r);
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
n = v.size();
for(int i = ; i <= * n; i++) {
f[i] = i;
}
} int find(int x) {
return lower_bound(v.begin(), v.end(), x) - v.begin() + ;
} int get(int x) {
if(x == f[x]) {
return f[x];
}
int root = get(f[x]);
return f[x] = root;
} int main() {
scanf("%d %d", &n, &m);
init();
for(int i = ; i <= m; i++) {
int x = find(arr[i].l - );
int y = find(arr[i].r);
int x_odd = x, x_even = x + n;
int y_odd = y, y_even = y + n;
if(arr[i].ans == ) { //回答奇偶性相同
if(get(x_odd) == get(y_even)) { //与已知情况矛盾
printf("%d\n", i - );
return ;
}
f[get(x_odd)] = get(y_odd);
f[get(x_even)] = get(y_even);
} else { //回答奇偶性不同
if(get(x_odd) == get(y_odd)) { //与已知情况矛盾
printf("%d\n", i - );
return ;
}
f[get(x_odd)] = get(y_even);
f[get(x_even)] = get(y_odd);
}
}
printf("%d\n", m); //没有说谎
return ;
}
AcWing:239. 奇偶游戏(前缀和 + 离散化 + 带权并查集 + 异或性质 or 扩展域并查集 + 离散化)的更多相关文章
- AcWing 239.奇偶游戏 (带权并查集/种类并查集)
题意:你和朋友玩游戏,有个一\(01\)序列,你每次给出一个区间,朋友会回答这个区间中的\(1\)的个数是奇数还是偶数,但是你亲爱的朋友可能在撒谎,问在哪个询问你能确定你的朋友在撒谎,输出回合数. 题 ...
- acwing 239. 奇偶游戏 并查集
地址 https://www.acwing.com/problem/content/241/ 小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个 ...
- AcWing 239. 奇偶游戏
小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...
- POJ 1733 Parity game(离散化+带权并查集)
离散化+带权并查集 题意:长度为n的0和1组成的字符串,然后问第L和R位置之间有奇数个1还是偶数个1. 根据这些回答, 判断第几个是错误(和之前有矛盾)的. 思路:此题同HDU 3038 差不多,询问 ...
- POJ1733:Parity Game(离散化+带权并查集)
Parity Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12853 Accepted: 4957 题目链接 ...
- 【带权并查集】【离散化】vijos P1112 小胖的奇偶
每个区间拆成r和l-1两个端点,若之内有偶数个1,则这两个端点对应的前缀的奇偶性必须相同,否则必须相反. 于是可以用带权并查集维护,每个结点储存其与其父节点的奇偶性是否相同,并且在路径压缩以及Unio ...
- POJ 1733 Parity game 【带权并查集】+【离散化】
<题目链接> 题目大意: 一个由0,1组成的序列,每次给出一段区间的奇偶,问哪一条信息不合法. 解题分析: 我们用s[i]表示前i个数的前缀和,那么a b even意味着s[b]和s[a- ...
- Parity game(带权并查集+离散化)
题目链接 //kuangbin 题意: 现在你和你的朋友正在玩一种游戏. 你的朋友写下一串0和1的序列,然后你选择其中一串子序列(如[3,5])并且问他这个序列是包含奇数个1还是偶数个1(和是奇数还 ...
- .htaccess中301强制跳转到带www前缀或不带www的域名
相信很多站长朋友都有这样的的问题出现.即带www前缀的域名与不带www前缀的顶级域名收录情况是不同的.这个问题主要是由于搜索引擎对于顶级域名与二级域名权重判定不同造成的.毫无疑问地,唯一的域名能够给你 ...
随机推荐
- Codeforces 1189F. Array Beauty
传送门 首先可以注意到序列里面元素的顺序对答案是没有影响的,所以二话不说先排序再看看怎么搞 考虑枚举每种子序列可能产生的贡献并算一下产生这个贡献的子序列有多少 考虑设 $F(x)$ 表示选择的元素差值 ...
- configure,make和make install关系
linux编译安装中configure.make和make install各自的作用 ./configure是用来检测你的安装平台的目标特征的.configure根据给定的参数和系统环境会生成Make ...
- HTTP协议探究(三):HTTPS
一 复习与目标 1 复习 代理:转发通信数据(一般协议不变,作为中间人,可对报文进行过滤修改) 网关:转发通信数据(协议改变,作为资源拥有者) 隧道:转发通信数据(协议不变,作为管道,不对报文进行过滤 ...
- MongoDB实战读书笔记(一):JavaScript shell操作MongoDB
1 基本增删改查 基本概念: 数据库:同关系型数据库 集合:类似关系型数据库的表 文档:类似关系型数据库的行 字段:类似关系型数据库的列 操作: insert:新增,若新增数据的主键已经存在,则会抛异 ...
- JavaScript 的查询机制——LHS 与 RHS
JavaScript 引擎在查找一个变量的时候,有两种查找机制:LHS 和 RHS. RHS 的查询是简单地查找到某个变量的值,而 LHS 则是试图找到变量的容器的本身. 一个简单的例子:当我们执行 ...
- 统一用户认证系统CUAS实现要点
背景: 基于目前存在多套员工使用的日常工作子系统,现状为各系统各自有一套用户体系,员工需要记住各系统的用户名.密码等信息,还需要登录多个系统,重复工作量颇多.统一用户认证组件将用户名.密码等信息统一存 ...
- Spring @Scheduled执行原理解析
项目使用很多@Scheduled(cron=**) 注解来实现定时任务,既然要用就必须弄清楚的它的实现原理,于是乎翻了一下相关的源码. Spring 3.0之后增加了调度器功能,提供的@Schedul ...
- 【Distributed】互联网安全架构
一.常见Web安全漏洞 1.1 XSS攻击 什么是XSS攻击手段 如何防御XSS攻击 1.2 SQL注入攻击 什么是SQL注入 SQL注入防攻击手段 MyBatis #与$区别 1.3 Http请求防 ...
- Django—ModelForm
简介 Model + Form ==> ModelForm.model和form的结合体,所以有以下功能: 验证 数据库操作 Form回顾 models.py class UserType(mo ...
- Comparing Sentence Similarity Methods
Reference:Comparing Sentence Similarity Methods,知乎.