ural 1003 Parity
有一个长度为$n$的$01$序列,有$k$组已公开情报,第$i$组为下标在$[l_i,r_i]$的元素的和的奇偶性为$o_i$
问第一个有冲突的情报是哪个
如果都没有冲突,输出$k$
十分巧妙的带权并查集
先对序列做前缀异或和,这样情报就转化为了$s_r \oplus s_{l-1}=o$
也就是说$s_r$和$s_{l-1}$的距离为$o$,用带权并查集维护一下就行了
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5 + 10; 4 map<int, int> id; int tot; 5 int n, m; 6 struct T { int l, r, o; } t[N]; 7 8 int fa[N], dis[N]; 9 10 int get(int x) { 11 if(x == fa[x]) return x; 12 int f = get(fa[x]); 13 dis[x] ^= dis[fa[x]]; 14 return fa[x] = f; 15 } 16 17 int merge(int x, int y, int o) { 18 int fx = get(x), fy = get(y); 19 if(fx == fy) return dis[x] ^ dis[y] == o; 20 fa[fx] = fy; 21 dis[fx] = dis[x] ^ dis[y] ^ o; 22 return 1; 23 } 24 25 void sol() { 26 tot = 0, id.clear(); 27 scanf("%d", &m); 28 for(int i = 1 ; i <= m ; ++ i) { 29 char s[10]; int l, r; 30 scanf("%d%d%s", &l, &r, s); 31 if(id[r] == 0) id[r] = ++ tot; 32 if(id[l - 1] == 0) id[l - 1] = ++ tot; 33 t[i] = (T) { id[l - 1], id[r], s[0] == 'o' }; 34 } 35 for(int i = 1 ; i <= tot ; ++ i) fa[i] = i, dis[i] = 0; 36 for(int i = 1 ; i <= m ; ++ i) { 37 int x = t[i].l, y = t[i].r, o = t[i].o; 38 if(!merge(x, y, o)) { 39 printf("%d\n", i - 1); 40 return ; 41 } 42 } 43 printf("%d\n", m); 44 } 45 46 int main() { 47 while(scanf("%d", &n) == 1 && n != -1) sol(); 48 }