[POJ1733]Parity game(并查集 + 离散化)

传送门

题意:有一个长度已知的01串,给出[l,r]这个区间中的1是奇数个还是偶数个,给出一系列语句问前几个是正确的

思路:如果我们知道[1,2][3,4][5,6]区间的信息,我们可以求出[1,6]的信息

   可以将将闭区间[x,y]转换成(x - 1,y]左开右闭区间

   那么我们可以用并查集来做,每次输入两个数 x 和 y 判断两者是否在同一并查集中,如果在,那么可以直接判断奇偶

   如果两者不在同一并查集中将两者合并,并求出两者的根之间的距离

   距离可在 find 函数中维护

注意:数据范围比较大,需要离散化

——代码

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #define N 1000001
 5 
 6 int n, m, cnt, ans;
 7 int a[N], b[N], q[N << 1], f[N << 1], d[N << 1];
 8 char s[N][10];
 9 
10 inline int read()
11 {
12     int x = 0, f = 1;
13     char ch = getchar();
14     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
15     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
16     return x * f;
17 }
18 
19 inline int find(int x)
20 {
21     if(x ^ f[x])
22     {
23         int fx = f[x];
24         f[x] = find(f[x]);
25         d[x] = d[x] ^ d[fx];
26     }
27     return f[x];
28 }
29 
30 int main()
31 {
32     int i, x, y, fx, fy;
33     while(scanf("%d", &n) != EOF)
34     {
35         m = read();
36         ans = cnt = 0;
37         for(i = 1; i <= m; i++)
38         {
39             a[i] = read() - 1;
40             b[i] = read();
41             scanf("%s", s[i]);
42             q[++cnt] = a[i];
43             q[++cnt] = b[i];
44         }
45         std::sort(q + 1, q + cnt + 1);
46         cnt = std::unique(q + 1, q + cnt + 1) - q - 1;
47         for(i = 1; i <= cnt; i++) f[i] = i, d[i] = 0;
48         for(i = 1; i <= m; i++)
49         {
50             x = std::lower_bound(q + 1, q + cnt + 1, a[i]) - q;
51             y = std::lower_bound(q + 1, q + cnt + 1, b[i]) - q;
52             fx = find(x);
53             fy = find(y);
54             if(fx == fy)
55             {
56                 if((d[x] == d[y]) == (s[i][0] == 'o')) break;
57             }
58             else
59             {
60                 f[fx] = fy;
61                 d[fx] = d[x] ^ d[y] ^ (s[i][0] == 'o');
62             }
63             ans++;
64         }
65         printf("%d
", ans);
66     }
67     return 0;
68 }
View Code
原文地址:https://www.cnblogs.com/zhenghaotian/p/7015882.html