上题目
例一:奇偶游戏
题目描述
你和你的朋友玩一个游戏。你的朋友写下来一连串的0或者1。你选择一个连续的子序列然后问他,这个子序列包含1的个数是奇数还是偶数。你的朋友回答完你的问题,接着你问下一个问题。
你怀疑你朋友的一些答案可能是错误的,你决定写一个程序来帮忙。程序将接受一系列你的问题及你朋友的回答,程序的目的是找到第一个错误的回答i,也就是存在一个序列满足前i-1个问题的答案,但是不满足前i个问题。
输入
第一行有一个整数L(L<=1000000000),是这个01序列的长度。第二行是一个整数N(N<=5000),是问题及其答案的数目,接下来N行描述问题和答案。每一行包含一个问题和这个问题的答案:两个整数(子序列的起始位置和结束位置)和一个单词‘even’或者‘odd’,‘even’表示这个子序列中的‘1’的个数是偶数,‘odd’则表示是奇数。
输出
输出一行一个整数X。表示存在一个01序列满足前面的X个问题,但是不存在一个01序列满足前X+1个问题,如果存在一个序列满足所有问题,则输出N。
样例输入
10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
样例输出
3
数据范围:
序列长度L<=1000000000,询问及回答数N<=5000
分析: 又是找和之前的有矛盾的,所以想到了并查集(实际上是老师帮我们把题目归了类...要是我应该想不到吧...
扩展域并查集。
若[a,b]中出现了偶数个1,则表示[0,a-1]和[0,b]的1的奇偶性相同。
若[a,b]中出现了奇数个1,则表示[0,a-1]和[0,b]的1的奇偶性不同。
这样就可以用并查集来维护:
fa[i]代表[0,i]有偶数个1,fa[i+len]代表[0,i]有奇数个1。
若[a,b]有偶数个1,则合并fa[a-1]和fa[b],fa[a-1+len]和fa[b+len]。
若[a,b]有奇数个1,则合并fa[a-1]和fa[b+len],fa[a-1]和fa[b+len]。
对于每次操作,提前查询一下另一种回答所对应的集合是否是同一个,来判断是否矛盾。
这个题需要离散化,因为查询[a,b]时要使用的是a-1,不能离散化后再减1,因为这时候减的1实际可能代表的并不是一个单位,有可能是一个区间,因为你离散掉了。要做的就是在读入的时候就a--,这样就可以了。