题意:
给出区间内有奇数(偶数)个’1’,在第x行与前面有冲突,求x,输出x-1。
思路:
带权并查集,权值为1或0表示当前节点与父节点之间有奇数或偶数个’1’,更新操作可以使用异或。因为数据范围大所以需要离散化。
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
int n, m;
struct node{
int u,v;
char ch[3];
}P[5000+100];
int fa[5000+100], val[5000+100];
int p[5000+100];
void init()
{
for (int i = 0; i <= 5000; i++)
{
fa[i] = i;
val[i] = 0;
}
}
int Serch(int x, int cnt)
{
int low = 0, high = cnt-1, mid;
while (low<=high)
{
mid = (low+high)>>1;
if (p[mid]==x) return mid;
if (p[mid]<x) low = mid+1;
else high = mid-1;
}
return -1;
}
int Find(int x)
{
if (x==fa[x]) return x;
int t = fa[x];
fa[x] = Find(fa[x]);
val[x] ^= val[t];
return fa[x];
}
int main(void)
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d %d", &n, &m);
init();
int ans = 0;
int k = 0;
for (int i = 0; i < m; i++)
{
scanf("%d %d %s", &P[i].u, &P[i].v, P[i].ch);
P[i].u--;
p[k++] = P[i].u;
p[k++] = P[i].v;
}
sort(p,p+k);
k = unique(p,p+k)-p;
for (int i = 0; i < m; i++, ans++)
{
int u = Serch(P[i].u,k), v = Serch(P[i].v, k);
int a = Find(u);
int b = Find(v);
if (a==b)
{
int t = P[i].ch[0]=='o'?1:0;
if (val[u]^val[v] != t)
break;
}
else
{
fa[b] = a;
val[b] = val[u]^val[v]^(P[i].ch[0]=='o'?1:0);
}
}
printf("%d\n",ans);
return 0;
}