VijosP1112:小胖的奇偶

描述

huyichen和xuzhenyi在玩一个游戏:他写一个由0和1组成的序列。

huyichen选其中的一段(比如第3位到第5位),问他这段里面有奇数个1
还是偶数个1。xuzhenyi回答你的问题,然后huyichen继续问。

xuzhenyi有可能在撒谎。huyichen要检查xuzhenyi的答案,指出在xuzhenyi的第几个回答一定有问题。

有问题的意思就是存在一个01序列满足这个回答前的所有回答,而且不存在序列
满足这个回答前的所有回答及这个回答。

格式

输入格式

第1行一个整数,是这个01序列的长度(<=1000000000)
第2行一个整数,是问题和答案的个数。

第3行开始是问题和答案,
每行先有两个整数,表示你询问的段的开始位置和结束位置。

然后是xuzhenyi的回答。odd表示有奇数个1,even表示有偶数个1。

输出格式

输出一行,一个数X,表示存在一个01序列满足第1到第X个回答,
但是不存在序列满足第1到第X+1个回答。如果所有回答都没问题,你就输出
所有回答的个数。

输入:

10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd

输出

3

思路:l r even 等价于0-l-1与0-R的序列奇偶性相同。odd等价于奇偶性相反。对x进行hash时,其在hash数组中的位置表示其hash值。

#include<cstdio>
#include<cstring>
using namespace std;
const int MOD=1000007;
int Hash[MOD];
int par[MOD+MOD];
int HASH(int x)
{
    int t=x%MOD;
    while(Hash[t]!=-1&&Hash[t]!=x)
        t=(t+1)%MOD;
    Hash[t]=x;
    return t;
}
void prep()
{
    for(int i=0;i<MOD+MOD;i++)
    {
        par[i]=i;
    }
}
int fnd(int x)
{
    if(x==par[x])
        return x;
    return par[x]=fnd(par[x]);
}

void unite(int x,int y)
{
    int a=fnd(x);
    int b=fnd(y);
    par[a]=b;
}
bool same(int x,int y)
{
    return fnd(x)==fnd(y);
}
int main()
{
    memset(Hash,-1,sizeof(Hash));
    int n,m;
    scanf("%d%d",&n,&m);
    int res=m;
    prep();
    for(int i=0;i<m;i++)
    {
        int l,r;
        char s[5];
        scanf("%d%d%s",&l,&r,s);
        if(res!=m)
            continue;
        int a=HASH(l-1);
        int b=HASH(r);
        if(s[0]==‘e‘)
        {
            if(same(a,b+MOD))
            {
                res=i;
            }
            unite(a,b);
            unite(a+MOD,b+MOD);
        }
        else
        {
            if(same(a,b))
            {
                res=i;
            }
            unite(a,b+MOD);
            unite(a+MOD,b);
        }
    }
    printf("%d\n",res);
    return 0;
} 
时间: 2025-01-02 18:50:07

VijosP1112:小胖的奇偶的相关文章

【带权并查集】【离散化】vijos P1112 小胖的奇偶

每个区间拆成r和l-1两个端点,若之内有偶数个1,则这两个端点对应的前缀的奇偶性必须相同,否则必须相反. 于是可以用带权并查集维护,每个结点储存其与其父节点的奇偶性是否相同,并且在路径压缩以及Union时进行分类讨论即可. 由于n太大,要对两个端点进行离散化. #include<cstdio> #include<algorithm> using namespace std; int fa[10010]; bool rel[10010]; int findroot(int x){ i

LNSYOJ201小胖的奇偶【并查集+离散化】【做题报告】

这道题是一个带权并查集 题目描述 huyichen和xuzhenyi在玩一个游戏:他写一个由0和1组成的序列. huyichen选其中的一段(比如第3位到第5位),问他这段里面有奇数个1 还是偶数个1.xuzhenyi回答你的问题,然后huyichen继续问. xuzhenyi有可能在撒谎.huyichen要检查xuzhenyi的答案,指出在xuzhenyi的第几个回答一定有问题. 有问题的意思就是存在一个01序列满足这个回答前的所有回答,而且不存在序列 满足这个回答前的所有回答及这个回答. 输

小胖的奇遇——论玄学

小胖的奇偶 题目描述: huyichen和xuzhenyi在玩一个游戏:他写一个由0和1组成的序列.huyichen选其中的一段(比如第3位到第5位),问他这段里面有奇数个1还是偶数个1.xuzhenyi回答你的问题,然后huyichen继续问.xuzhenyi有可能在撒谎.huyichen要检查xuzhenyi的答案,指出在xuzhenyi的第几个回答一定有问题.有问题的意思就是存在一个01序列满足这个回答前的所有回答,而且不存在序列满足包括这个回答在内的所有回答,也就是自相矛盾. 输入格式:

BZOJ 3714 PA 2014 Kuglarz 最小生成树

题目大意:桌面上倒扣着一些杯子,在这些杯子的有一些杯子底下有小球.可以询问i到j号杯子下面共有多少个小球的奇偶性,花费c[i][j],问至少花费多少可以得知杯子下面小球的存在情况. 思路:看这个题怎么看怎么想小胖的奇偶,其实是一样的,只不过这个题是利用了那个题的结论.没做过的可以先做做那个题,用并查集维护一下.那么这个题就很裸了,只是一个最小生成树的过程. CODE: #include <cstdio> #include <cstring> #include <iostrea

TYVJ并查集

神奇的并查集 P1017 冗余关系 当年刚刚学会并查集,合并写的是rank(),ce了好多次 #include <cstdio> int father[5001]; int m,n,c,d,a; int find(int a){ return (father[a]==a) ? a : (father[a]=find(father[a])); } int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=m;i++

POJ1733 Parity game (美丽的jo)

Description Now and then you play the following game with your friend. Your friend writes down a sequence consisting of zeroes and ones. You choose a continuous subsequence (for example the subsequence from the third to the fifth digit inclusively) a

Tempter of the Bone(dfs奇偶剪枝)

Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 92175    Accepted Submission(s): 25051 Problem Description The doggie found a bone in an ancient maze, which fascinated him a

hdu1010Tempter of the Bone(dfs+奇偶剪枝)

题目链接:点击打开链接 题目描述:给定一个迷宫,给一个起点和一个终点,问能否恰好经过T步到达终点?每个格子不能重复走 解题思路:dfs+剪枝 剪枝1:奇偶剪枝,判断终点和起点的距离与T的奇偶性是否一致,如果不一致,直接剪掉 剪枝2:如果从当前到终点的至少需要的步数nt加上已经走过的步数ct大于T,即nt+ct>t剪掉 剪枝3:如果迷宫中可以走的格子小于T直接剪掉 启发:剪枝的重要性 代码: #include <cstdio> #include <cstdlib> #inclu

Openjudge-计算概论(A)-整数奇偶排序

描述: 输入10个整数,彼此以空格分隔重新排序以后输出(也按空格分隔),要求:1.先输出其中的奇数,并按从大到小排列:2.然后输出其中的偶数,并按从小到大排列.输入任意排序的10个整数(0-100),彼此以空格分隔输出按照要求排序后输出,由空格分隔样例输入 4 7 3 13 11 12 0 47 34 98 样例输出 47 13 11 7 3 0 4 12 34 98 提示1. 测试数据可能有很多组,请使用while(cin>>a[0]>>a[1]>>...>&g