• 0x40数据结构进阶(0x41 并查集)例题3:奇偶游戏(题解)


    题意

    题目链接

    【题意】
     小A和小B在玩一个游戏。
     首先,小A写了一个由0和1组成的序列S,长度为N。
     然后,小B向小A提出了M个问题。
     在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个1。
     机智的小B发现小A有可能在撒谎。
     例如,小A曾经回答过 S[1~3] 中有奇数个1, S[4~6] 中有偶数个1,现在又回答 S[1~6] 中有偶数个1,显然这是自相矛盾的。
     请你帮助小B检查这M个答案,并指出在至少多少个回答之后可以确定小A一定在撒谎。
     即求出一个最小的k,使得01序列S满足第1~k个回答,但不满足第1~k+1个回答。
    
     【输入格式】
     第一行包含一个整数N,表示01序列长度。
     第二行包含一个整数M,表示问题数量。
      接下来M行,每行包含一组问答:两个整数l和r,以及回答“even”或“odd”,用以描述S[l~r] 中有奇数个1还是偶数个1。 
    补充:odd是奇数,even是偶数。 
    
     【输出格式】
     输出一个整数k,表示01序列满足第1~k个回答,但不满足第1~k+1个回答,如果01序列满足所有回答,则输出问题总数量。
    
     【数据范围】
    N≤10^9,M≤10000
    
    【输入样例】
    10
     5
     1 2 even
     3 4 odd
     5 6 even
     1 6 even
     7 10 odd
    
    【输出样例】
    3
    

    题解

    乍一看,这道题目没有什么思路。

    但是仔细一想,我们发现了一个事情:([2,4])([3,5])的奇偶性质互不影响,虽然有交集。

    所以我们就可以认为即使两个区间有很大部分交集,可是他们的奇偶性质互相还是没有多大的影响的,除非他们的交集部分也明确给出了奇偶或者可以算出奇偶。

    但是加入给你一个区间:([1,3],[4,5])如何合并成([1,5])的奇偶性质呢?

    很明显我们可以化成((0,3],(3,5]),然后合并成((0,5])的奇偶性质,然后用个权值并查集就OK了。

    但是(n)这么大!

    那我们就离散化呀!!!!

    离散化的正确性怎么保证?

    我们设([a,b])区间中,没有任何一个子区间能够确定奇偶性质,那么我们就可以把([a,b])化成一个数字,奇数就是(1),偶数就是(0)

    但是为了离散化的方便,我们可以把数字排序起来,如果间隔只是(1),那么离散化值差就是(1),但是如果间隔大于(1),离散化之差就是(2)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define  N  41000
    using  namespace  std;
    int  fa[N],val[N];
    int  findfa(int  x)
    {
    	if(fa[x]==x)return  x;
    	int  y=findfa(fa[x]);val[x]=val[x]^val[fa[x]];fa[x]=y;
    	return  y;
    }
    struct  problem
    {
    	int  l,r,type;
    }a[N];
    int  ls[N],what[N],cnt;
    bool  cmp(int  x,int  y){return  ls[x]<ls[y];}
    int  n,m,nn;
    int  main()
    {
    	scanf("%d%d",&nn,&m);
    	for(int  i=1;i<=m;i++)
    	{
    		char  ss[20];
    		scanf("%d%d%s",&ls[(i<<1)-1],&ls[i<<1],ss+1);
    		what[(i<<1)-1]=(i<<1)-1;what[i<<1]=i<<1;a[i].type=(ss[1]=='o');
    	}
    	sort(what+1,what+(m<<1)+1,cmp);
    	ls[0]=ls[1]-2;
    	for(int  i=1;i<=(m<<1);i++)
    	{
    		int  x=what[i],y=what[i-1];
    		if(ls[x]>ls[y]+1)cnt+=2;
    		else  if(ls[x]==ls[y]+1)cnt++;
    		if(x&1)a[(x+1)>>1].l=cnt;
    		else  a[(x+1)>>1].r=cnt;
    	}
    	//离散化
    	for(int  i=1;i<=cnt;i++)fa[i]=i;
    	for(int  i=1;i<=m;i++)
    	{
    		a[i].l--;
    		int  tx=findfa(a[i].l),ty=findfa(a[i].r);
    		if(tx==ty)
    		{
    			if(val[a[i].l]^val[a[i].r]!=a[i].type)
    			{
    				printf("%d
    ",i-1);
    				return  0;
    			}
    		}
    		else
    		{
    			fa[tx]=ty;
    			val[tx]=val[a[i].l]^val[a[i].r]^a[i].type;
    		}
    	}
    	//乱搞
    	printf("%d
    ",m);
    	return  0;
    }
    
  • 相关阅读:
    基于.net EF6 MVC5+WEB Api 的Web系统框架总结(2)-业务项目搭建
    基于Html5 Plus + Vue + Mui 移动App开发(三)-文件操作(读取、保存、更新数据)
    基于Html5 Plus + Vue + Mui 移动App 开发(二)
    Mysql数据库(一)-------安装
    Sublime---破解+安装+安装插件
    Bayboy功能详解
    MySQL基础语句
    python变量类型&字符串的内建函数使用
    数据库基础知识笔试题(一)
    软件测试笔试题(二)
  • 原文地址:https://www.cnblogs.com/zhangjianjunab/p/11737496.html
Copyright © 2020-2023  润新知