正题
POJ题目链接:http://poj.org/problem?id=1733
jzoj题目链接:https://jzoj.net/senior/#main/show/1779
题目大意
长度为ll的01串,个答案,表示一段区间内有偶数或奇数个1,求最多前多少个答案是对的。
解题思路
我们可以先离散化一下,然后我们再用并查集,然后两个点直接的并查集和权值表示这两个点之间1的奇偶。然后每次合并和压缩路径的时候就用异或操作。
code
#include<cstdio>
#include<algorithm>
using namespace std;
struct node{int l,r,ans;
}q[5010];
int l,n,f[5010],d[5010],a[5010*2],tot;
char c[5];
int find(int x){if(x==f[x]) return x;int fa=find(f[x]);d[x]^=d[f[x]];return f[x]=fa;
}//压缩路径
int main()
{scanf("%d%d",&l,&n);for(int i=1;i<=n;i++){scanf("%d %d %s",&q[i].l,&q[i].r,&c);if(c[0]=='e') q[i].ans=0;else q[i].ans=1;a[++tot]=q[i].l-1;a[++tot]=q[i].r;}//以上是输入sort(a+1,a+tot+1);l=unique(a+1,a+tot+1)-a-1;//以上是离散for(int i=1;i<=l;i++) f[i]=i;//初始化并查集for(int i=1;i<=n;i++){int x=lower_bound(a+1,a+1+l,q[i].l-1)-a;int y=lower_bound(a+1,a+1+l,q[i].r)-a;//找到位置int fa=find(x),fb=find(y);if(fa==fb){if(d[x]^d[y]!=q[i].ans){printf("%d",i-1);return 0;}//不符合}elsef[fa]=fb,d[fa]=d[x]^d[y]^q[i].ans;//连接}printf("%d",n);
}