Parity game 奇偶游戏(离散化+前缀和+带权并查集)

题目链接
这个链接的地址是acwing的 在这个oj上提交可以看到测试数据。
本题有关带权并查集 先分享一下大神的博客 链接

题目描述

小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满足第1k个回答,但不满足第1k+1个回答。

输入格式

第一行包含一个整数N,表示01序列长度。

第二行包含一个整数M,表示问题数量。

接下来M行,每行包含一组问答:两个整数l和r,以及回答“even”或“odd”,用以描述S[l~r] 中有奇数个1还是偶数个1。

输出格式

输出一个整数k,表示01序列满足第1k个回答,但不满足第1k+1个回答,如果01序列满足所有回答,则输出问题总数量。

数据范围

N≤109,M≤10000

输入样例:

10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd

输出样例:

3

首先告诉了你区间[a,b]内1的个数的奇偶性,那么根据前缀和思想,该区间内1的个数等于区间[1,b]内1的个数减去区间[1,a-1]内1的个数。
另外,我们可以知道奇偶性的性质:
奇 + 奇 = 偶
奇 + 偶 = 奇
偶 + 偶 = 偶
如果我们设奇为1,偶为0,就可以用带权并查集的思想将就奇偶性转化为权值了。

同时本题N的范围较大,需要先将输入数据离散化处理。

离散化,俺也不太懂,上百度百科:
离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。
通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。例如:
原数据:1,999,100000,15;处理后:1,3,4,2;
原数据:{100,200},{20,50000},{1,400};
处理后:{3,4},{2,6},{1,5};

虽然N的数据范围很大,但询问的范围却只有5000,而且这题我们只需比较区间信息,所以我们可以对已有的数据进行排序去重处理,在需要时进行查询,找到数据之间的相对位置。这时就要用到STL库中的去重和查找函数了。

先定义已有一个已排好序的整型数组f[n]

去重函数
unique():h=unique(f,f+n)-f;//去重
返回去重后元素的个数,注意在使用前先用sort函数排序

查找函数
lower_bound():lower_bound(f,f+h,a)-f;//索引
返回元素a在数组f[h]中的位置

最后再套带权并查集模板并注意细节

AC代码:

#include
#include
#include
#include
#include
using namespace std;
int pre[500005],re[500005],cot,cnt,f[

你可能感兴趣的:(Parity game 奇偶游戏(离散化+前缀和+带权并查集))