题目链接:https://ac.nowcoder.com/acm/problem/51097

题意描述

输入给出了多组区间[xi,yi]中数字1的数量的奇偶性,要求我们根据已有的条件判断该下一数据是否能成立,若能成立则将其纳入条件,反之输出该条件的编号。

解析

对于已有条件我们可以这样考虑,将区间[xi,yi]中数字1的数量的奇偶性转换为区间[0,xi-1]与区间[xi,yi]中数字1的奇偶性是否相同。

开一个unordered_map维护一个并查集,并查集分为两部分,一部分为奇数个1的前缀和,另一部分为偶数个1前缀和,由于从第一组数据开始就形成两种可能性,分别形成两组集合,若某组区间两前缀和所属的集合不符合数据奇偶性的描述,输出该条件的编号即可。

#include<bits/stdc++.h>
using namespace std;
unordered_map<int,int>fa;
int find(int x){
    return x==fa[x]? x : fa[x]=find(fa[x]);
}
void merge(int x,int y){
    fa[find(x)]=find(y);
}
int main(){
    int len;cin>>len;
    int q,ans;cin>>q;ans=q;
    len++;//区分奇偶
    for(int i=0;i<q;i++){
        int x,y;cin>>x>>y;
        if(!fa.count(y))fa[y+len]=y+len,fa[y]=y;//一定要判断是否出现过
        if(!fa.count(x-1))fa[x+len-1]=x+len-1,fa[x-1]=x-1;//同上
        string s;cin>>s;
        if(s=="even"){
            if(find(x-1)==find(y+len)||find(x+len-1)==find(y)){//两个取一个即可,二者等价
                ans=i;
                break;
            }else{
                merge(x-1,y);
                merge(x-1+len,y+len);
            }
        }else{
           if(find(x-1)==find(y)||find(x-1+len)==find(y+len)){
               ans=i;
               break;
           }else{
               merge(x-1,y+len);
               merge(x-1+len,y);
           }
        }
    }
    cout<<ans<<endl;
    return 0;
}