Vijos P1112 小胖的奇偶
并查集!
对于一段区间(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; }