poj 1733
有字符串,由$0$和$1$组成,给出几个区间,并且告诉你区间里面$1$的个数的奇偶性,假设前面的话都是对的,问你到哪一句和前面的话矛盾。
这种题肯定想图论问题。
对于区间,转化为前缀和相减。那么前缀和奇偶性相不相同就能确定了。
若区间为奇数则奇偶性不同,否则奇偶性相同。
然后拆点并查集判关系即可。
对于区间,转化为前缀和相减
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<cmath>
#define ms(i, j) memset(i, j, sizeof i)
#define LL long long
#define db double
#define fir first
#define sec second
#define mp make_pair
using namespace std;
namespace flyinthesky {
struct data {
int l, r, x;
} opt[5000 + 5];
int m, q, whw[10000 + 5], gg;
int f[20000 + 5];
int getRealID(int x) {return lower_bound(whw + 1, whw + 1 + gg, x) - whw;}
int find(int x) {return f[x] == x ? x : f[x] = find(f[x]);}
void clean() {
gg = 0;
}
int solve() {
clean();
scanf("%d%d", &m, &q);
for (int i = 1; i <= q; ++i) {
char s[10]; scanf("%d%d%s", &opt[i].l, &opt[i].r, s);
if (s[0] == 'e') opt[i].x = 0; else opt[i].x = 1;
whw[++gg] = opt[i].l - 1, whw[++gg] = opt[i].r;
}
sort(whw + 1, whw + 1 + gg), gg = unique(whw + 1, whw + 1 + gg) - whw - 1;
for (int i = 0; i <= 20000; ++i) f[i] = i;
for (int i = 1; i <= q; ++i) {
int x = find(getRealID(opt[i].l - 1)), y = find(getRealID(opt[i].r));
int xn = find(getRealID(opt[i].l - 1) + gg), yn = find(getRealID(opt[i].r) + gg);
if (x == y) { // 奇偶性相同
if (opt[i].x == 1) return printf("%d\n", i - 1), 0;
} else if (x == yn) {
if (opt[i].x == 0) return printf("%d\n", i - 1), 0;
}
if (opt[i].x == 0) f[x] = y, f[xn] = yn; else f[x] = yn, f[y] = xn;
}
printf("%d\n", q);
return 0;
}
}
int main() {
flyinthesky::solve();
return 0;
}