/* 返回顶部 */

Vijos P1112 小胖的奇偶

gate

并查集!

对于一段区间(L,R),若有奇数个一,则(1,L-1)和(1,R)奇偶性一定不同,反之亦然。

把奇偶性相同的区间连起来。

如果将i和i+N视为相反的状态,

假设A和B的奇偶性相同,则合并A,B,A+N,B+N。

不同,则合并A.B+N,A+N,B。

那么,每次给出一个回答,合并前先检查是否已经存在了和该回答相反的关系,若存在则为假。

有点类似于2-SAT。

代码如下

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
#include<map>
using namespace std;

int n,m,a,b;
char c[10];
map <int,int> fa;

int getfa(int x) {
    if(fa[x] == 0 || fa[x] == x) return x;
    return fa[x] = getfa(fa[x]);
}

int main() {
    scanf("%d%d",&n,&m);
    n++;
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%s",&a,&b,c);
        int a0 = getfa(a-1);
        int b0 = getfa(b);
        int a1 = getfa(a-1+n);
        int b1 = getfa(b+n);
        if(c[0] == 'o') {
            if(a0 == b0 || a1 == b1) {
                printf("%d",i-1);
                return 0;
            }
            fa[a0] = b1;
            fa[a1] = b0;
        }
        if(c[0] == 'e') {
            if(a0 == b1 || a1 == b0) {
                printf("%d",i-1);
                return 0;
            }
            fa[a0] = b0;
            fa[a1] = b1;
        }
    }
    printf("%d",m);
    return 0;
}
View Code
posted @ 2019-11-12 14:02  Mogeko  阅读(180)  评论(0编辑  收藏  举报