zoukankan      html  css  js  c++  java
  • 【CEOI 1999】奇偶性游戏

    Description

    你偶尔和朋友玩如下的游戏。你的朋友写下一个由01组成的序列。你选择连续的一段子序列(例如,从第3到第5个数的子序列),问他这一段中1的个数是偶数还是奇数。你的朋友会回答你的问题,然后你可以问他另外一段子序列,等等。你的任务是猜出整个序列。
    你怀疑你朋友的一些回答可能是错误的,并且你希望证明他说了假话。因此你决定写一个程序来帮助你。这个程序将会收到你的一系列问题以及你朋友给出的答案。 程序的目标是找到第一个被证明是错误的回答,即,存在一个序列能满足之前所有回答,但加上这个回答后就不存在相应的序列。

    Input

    第一行有一个整数,代表01序列的长度。长度不超过1000000000。
    第二行有一个正整数,代表询问和回答的数量。数量不超过5000.
    接下来的若干行描述了所有的了询问和回答。每一行包含了一个询问和对此询问的回答:两个整数(所选择的子序列的起止点),一个单词“even”或“odd”(答案,即该子序列中1的个数的奇偶性),其中“even”代表有偶数个,“odd”代表有奇数个。

    Output

    输出一个整数X。它意味着:存在一个01序列满足前X个奇偶性询问,但不存在满足前X+1个奇偶性询问的序列。如果存在满足所有询问的序列,X就应该是询问的总数。

    Sample Input

    输入样例1:

    10

    5

    1 2 even

    3 4 odd

    5 6 even

    1 6 even

    7 10 odd
    输入样例2:

    10

    5

    1 2 even

    1 4 even

    2 4 odd

    1 10 even

    3 10 even

    1 2 even

    Sample Output

    输出样例1:

    3

    输出样例2:

    5

    Hint

    Source

    CEOI 1999 Parity game
    并查集

    思路{

      此题乃并查集大好题!!!!!!!!!!!!!!

      数据有1000000000,肯定离散化。离散化后,顺着离散化的思路,就连边。

      又要保证点的连通性,把区间左端点-1或右端点+1

      随后,用并查集维护,合并2个端点,连双向边(由于之后要统计更大的区间)

      如果两个端点在一个集合内,爆搜判断即可(正确性显然!)

    }

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<queue>
     7 #include<ctime>
     8 #include<cmath>
     9 #include<list>
    10 #include<deque>
    11 #include<stack>
    12 #include<map>
    13 #include<set>
    14 #define RG register
    15 #define LL long long
    16 #define dd double
    17 #define maxx 10001
    18 using namespace std;
    19 int fa[maxx],tong[maxx],tot;
    20 map<int,int>m;
    21 struct ed{
    22 int nxt,to,c;
    23 }e[maxx*10];int head[maxx];
    24 int find(int x){if(fa[x]!=x)return fa[x]=find(fa[x]);return fa[x];}
    25 void Insert(int x,int y){fa[find(x)]=fa[find(y)];}
    26 LL L[(maxx/2)+1],R[(maxx/2)+1];int ww[(maxx/2)+1];
    27 void add(int u,int v,int c){
    28   e[tot].nxt=head[u];
    29   e[tot].to=v;
    30   e[tot].c=c;
    31   head[u]=tot++;
    32 }
    33 int dfs(int s,int t,int faa,int num){
    34   if(s==t)return num&1;
    35   for(int i=head[s];i!=-1;i=e[i].nxt)if(e[i].to!=faa){
    36       int kk=dfs(e[i].to,t,s,num^e[i].c);
    37       if(kk!=-1)return kk;
    38     }return -1;
    39 }
    40 int main(){
    41   memset(head,-1,sizeof(head));
    42   int n,mm;scanf("%d%d",&n,&mm);
    43   for(int i=1;i<=mm;++i){
    44     scanf("%lld%lld",&L[i],&R[i]);L[i]--;
    45     char ch[12];scanf("%s",ch);
    46     ww[i]=(ch[0]=='o');
    47     tong[(i<<1)-1]=L[i],tong[(i<<1)]=R[i];
    48   }sort(tong+1,tong+mm*2+1);int s=0;
    49   for(int i=1;i<=2*mm;++i)if(tong[i]!=tong[i-1])m[tong[i]]=++s;
    50   for(int i=1;i<=s;++i)fa[i]=i;
    51   for(int i=1;i<=mm;++i){
    52     int a=m[L[i]],b=m[R[i]],c=ww[i];
    53     if(find(a)!=find(b))fa[find(a)]=fa[find(b)],add(a,b,c),add(b,a,c);
    54     else if(dfs(a,b,a,0)!=c){cout<<i-1,exit(0);}
    55   }cout<<mm;
    56   return 0;
    57 }
  • 相关阅读:
    MYSQL数据类型——字符串类型
    MYSQL——记录长度
    MYSQL数据类型——时间日期类型
    MYSQL数据类型——数值类型
    为什么在 IDEA jsp 中直接使用 out.println 会出错
    花指令行为大赏
    EasyCpp 题解
    [SUCTF2019] hardcpp 题解
    洛谷 P1650 田忌赛马题解
    Dict 协议是什么
  • 原文地址:https://www.cnblogs.com/zzmmm/p/6817372.html
Copyright © 2011-2022 走看看