POJ 1733 parity game

Question meaning: give you a n n, which means there is a string composed of 0 and 1 with a length of N, and then give you m operations a b op, where op is the sum of an even and b, o is the odd number, now ask you how many operations you found that he and the previous contradiction.

Train of thought: This is the first way to use the topic of discretization. The path compression operation and weight calculation of this problem with weighted parallel search set and the [Topic] written in the previous two days https://blog.csdn.net/yiqzq/article/details/80152561 For example, it is strongly recommended that the students who write and check the collection for the first time should study first. If you know the above question, the next thing you need to do is to discretize the interval. (explain why discretization is needed, because you will find that the interval given in the question is very long, with a range of 1e9. Obviously, if you open an array, you can't open such a large one. At this time, you will find that the number of queries given in the question is only 5000. In this case, assume that the interval is not repeated, It can only use 10000 points at most, so the extra space will not be wasted. Back to discretization, if you haven't studied, you can go This blog Go and study.

So this problem requires us to discretize the interval, not the value, so what should we do?
Solution: very simple, we only need to discretize the two end values of the interval.

What's more, how to calculate the weight? We can add up the results by% 2 each time.

for instance:
We know that interval [1,3] is odd, we record it as 1, interval [4,8] is even, we record it as 0, then the parity of interval [1,8] is (0 + 1)% 2 = 1
Code above:

#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int add = 4;
const int maxn = 50005;
int n, m,num[maxn] ,f[maxn], val[maxn];
struct node {
    int a, b, c;
} e[maxn];
int getf(int v) {
    if(f[v] == v) return v;
    int t = f[v];
    f[v] = getf(f[v]);
    val[v] = (val[v] + add + val[t]) % 2;//Update weight when compressing path
    return f[v];
}
void init() {
    for(int i = 0; i < maxn; i++) {
        val[i] = 0;
        f[i] = i;
        num[i] = 0;
    }
}
int main() {
init();
    int flag = 1;
    int cnt = 0;
    scanf("%d%d", &n, &m);
    char op[10];
    for(int i = 0; i < m; i++) {
        scanf("%d%d%s", &e[i].a, &e[i].b, op);
        e[i].a--;//Minus 1 is for the convenience of interval calculation. You can go to the above blog for details
        if(op[0] == 'e') e[i].c = 0;
        else e[i].c = 1;
        num[cnt++] = e[i].a;
        num[cnt++] = e[i].b;
    }
    /*
    General operation steps of discretization
    1.Copy data samples
    2.Sort with sort
    3.Using the unique function to de duplicate
    4.Use lower bound() mapping
    */
    sort(num, num + cnt);
    int k = unique(num, num + cnt) - num;
    for(int i = 0; i < m; i++) {
        int nx = lower_bound(num, num + k, e[i].a) - num;
        int ny = lower_bound(num, num + k, e[i].b) - num;
        int x = getf(nx);
        int y = getf(ny);
        if(x != y) {
            f[y] = x;
            val[y] = (val[nx] + e[i].c - val[ny] + add) % 2;//add one at a time to prevent negative numbers
        } else if(x == y && e[i].c != (val[ny] - val[nx] + add) % 2) {
            printf("%d\n", i);
            flag = 0;
            break;
        }
    }
    if(flag) printf("%d\n", m);
    return 0;
}

Posted on Thu, 26 Mar 2020 13:05:21 -0400 by clintonium