poj1733(种类并查集+离散化)

参考博客
题意:给m个区间和这个区间内1的个数是奇还是偶,然后输出第一个和前面相矛盾的区间的序号
思路:首先区间最大值有1e9,数组开不出来,而数据的输入量却很小,最多也就10000个数,所以先进行离散化处理区间的标号
区间内1的数量为偶就看成0,否则为1;因为我们不关心具体的数量;(x,y)的1的个数为奇数时,也就是x-1到y中间的1的个数为奇数,故可用(x-1) <- y,其中rela[y]=1,代表y和他的父节点之前的1的个数为奇数。其他就和食物链差不多。主要在于要看到(x,y)的1的个数和x-1<-y之间转换。

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<time.h>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<functional>
#include<stack>
#include<map>
#include<queue>
#define mod (1000000007)
#define middle (l+r)>>1
#define SIZE 10000+10
#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long ll;
const int inf_max = 0x3f3f3f3f;
const ll Linf = 9e18;
const int maxn = 50000+10;
const double eps=0.0001;
using namespace std;
int n,m,cnt,a[maxn],f[maxn],val[maxn],tmp[maxn];
struct Seg
{
    int l,r;
}seg[maxn];
int myfind(int x)
{
    if(x==f[x])
        return f[x];
    int t=f[x];
    f[x]=myfind(f[x]);
    val[x]=(val[t]+val[x])%2;
    return f[x];
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        int flag=0;
        for(int i=0;i<=m<<1;i++)
        {
            f[i]=i;val[i]=0;tmp[i]=0;
        }
        cnt=0;
        for(int i=1;i<=m;i++)
        {
            char s[10];
            scanf("%d%d%s",&seg[i].l,&seg[i].r,s);
            tmp[i]=(s[0]=='e')?0:1;
            a[cnt++]=seg[i].l;
            a[cnt++]=seg[i].r;
        }
        sort(a,a+cnt);
        int siz=unique(a,a+cnt)-a,ans=1;
        for(int i=1;i<=m;i++)
        {
            int l=lower_bound(a,a+siz,seg[i].l)-a+1;//返回的是下标,完全可能是0
            int r=lower_bound(a,a+siz,seg[i].r)-a+1;
            l--;
            int fl=myfind(l),fr=myfind(r);
            //printf("l=%d,r=%d,fl=%d,fr=%d\n",l,r,fl,fr);
            if(fl!=fr)
            {
                f[fr]=fl;
                val[fr]=(val[l]+tmp[i]-val[r]+2)%2;
            }
            else
            {
                if(tmp[i]!=(val[r]-val[l]+2)%2)
                {
                    flag=1;
                    //printf("haf\n");
                    ans=i;
                    break;
                }
            }
        }
//        for(int i=0;i<=7;i++)
//        {
//            printf("f[%d]=%d,val[%d]=%d\n",i,f[i],i,val[i]);
//        }
        if(flag)
            printf("%d\n",ans-1);
        else
            printf("%d\n",m);
    }
    return 0;
}
发布了33 篇原创文章 · 获赞 14 · 访问量 426

猜你喜欢

转载自blog.csdn.net/qq_44077455/article/details/103093844
今日推荐