题意
区间长度为n,给定m个关系,然后三个输入l,r,s(字符) ,如果s="even"表示(l,r) 有偶数个1,如果s="odd"表示(l,r) 有奇数个1,求k使得1-k个条件都能满足要求,而k+1个条件不能满足.
思路
边带权并查集,记录与父亲节点之间有偶数个1还是奇数个1,当权值为1时时偶数个1,当权值为0时为偶数个1.
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct node{
int l,r,id;
}a[maxn];
int t[maxn],fa[maxn],d[maxn];
int find(int x){
if(x==fa[x]) return x;
int fx=find(fa[x]);
d[x]^=d[fa[x]];
return fa[x]=fx;
}
int main(){
int n,m;scanf("%d%d",&n,&m);
int tot=0;
for(int i=1;i<=m;i++){
char s[5];
scanf("%d%d%s",&a[i].l,&a[i].r,s);
a[i].id=s[0]=='e'?0:1;
t[++tot]=a[i].l-1;
t[++tot]=a[i].r;
}
sort(t+1,t+tot+1);
tot=unique(t+1,t+tot+1)-t-1;
for(int i=1;i<=tot;i++) fa[i]=i;
int ans=m,flag=0;
for(int i=1;i<=m;i++){
int x=lower_bound(t+1,t+tot+1,a[i].l-1)-t;
int y=lower_bound(t+1,t+tot+1,a[i].r)-t;
int fx=find(x),fy=find(y);
if(fx==fy) {
if((d[x]^d[y])!=a[i].id){
ans=i-1;
flag=1;
break;
}
}
else {
fa[fx]=fy;
d[fx]=d[x]^d[y]^a[i].id;
}
}
printf("%d\n",ans);
//system("pause");
}