poj 1733 Parity game
有n个数字,不知道具体是多少,给q个信息。
每个信息给一个区间[l,r]。并告诉这个区间的奇数有多少个,问第一个错误的信息是第几个。
可以把每个区间的左端点-1的根看做右端点的根的根,用并查集维护一个到根点的1的个数是奇数还是偶数即可。
注意得离散化。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <map> using namespace std; const int M = 2e5+7; int n,q,tot=0; int f[M],cnt[M],l[M],r[M],op[M],ls[M],num[M]; map<int,int> mp; void init(int n){//0==even for(int i=0;i<=n;i++) f[i]=i,cnt[i]=0; } int find(int x){ if(x==f[x]) return x; int tmp=f[x]; f[x]=find(f[x]); cnt[x]^=cnt[tmp]; return f[x]; } int main(){ freopen("1.in","r",stdin); freopen("1.out","w",stdout); scanf("%d",&n); scanf("%d",&q); char s[10]; for(int i=1;i<=q;i++){ scanf("%d%d%s",&l[i],&r[i],s);l[i]-=1; if(s[0]=='o') op[i]=1; else op[i]=0; ls[++tot]=l[i];ls[++tot]=r[i]; } sort(ls+1,ls+tot+1); tot=unique(ls+1,ls+tot+1)-ls-1; init(tot); for(int i=1;i<=q;i++){ int posl=lower_bound(ls+1,ls+tot+1,l[i])-ls,posr=lower_bound(ls+1,ls+tot+1,r[i])-ls; int fx=find(posl),fy=find(posr); if(fx==fy){ if((cnt[posl]+op[i])%2!=cnt[posr]){ printf("%d\n",i-1); return 0; } } else{ f[fy]=fx; cnt[fy]=(2+cnt[posl]-cnt[posr]+op[i])%2; } } printf("%d\n",q); return 0; }