poj 1733 Parity game(种类并查集)

题意:

有0或1构成的一段区间总长度为n。m个询问,每次询问一段区间1的个数为奇数还是偶数,问从第一个询问開始,前几个询问正确的个数有几个;

思路:

n<=10^9,m<=5000;非常多数用不到,所以能够离散化一下;

将和为奇数的区间标记为1,为偶数的区间标记为0。

对于每一个询问,合并操作时。假设两区间重合且奇偶性之和与询问所给的奇偶性同样,则该询问正确,否则错误;

若区间不重合。合并区间,并合并奇偶性;

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
int n,m,t,cnt,ans;
char ch[10];
int fa[5000100],w[5000100];
void init()
{
    for(int i=0;i<5000100;i++)
    {
        fa[i]=i;w[i]=0;
    }
}
int find(int x)
{
    if(x==fa[x]) return x;
    int temp=fa[x];
    fa[x]=find(fa[x]);
    w[x]=(w[x]+w[temp])%2;
    return fa[x];
}
int combine(int x,int y,int d)
{
    int t1=find(x);
    int t2=find(y);
    if(t1==t2)
    {
        if((w[x]+w[y])%2==d) return 1; //奇偶性同样,则正确
        else return 0;
    }
    else{
        fa[t1]=t2;
        w[t1]=(w[x]+w[y]+d)%2; //更新区间奇偶性
        return 1;
    }
}
int main()
{
    int i,j,k,a,b,x,y,d;
    scanf("%d%d",&n,&m);
    init();
    map<int,int>mm;
    cnt=ans=0;
    for(i=0;i<m;i++)
    {
        scanf("%d%d%s",&a,&b,ch);a--;
        if(mm.find(a)==mm.end())
            mm[a]=cnt++;
        if(mm.find(b)==mm.end())
            mm[b]=cnt++;
        x=mm[a],y=mm[b];     //使用map实现离散化
        if(ch[0]==‘o‘) d=1;  //奇标记
        else d=0;            //偶标记
        if(combine(x,y,d)) ans++;
        else break;
    }
    printf("%d\n",ans);
}
时间: 2024-08-28 13:25:17

poj 1733 Parity game(种类并查集)的相关文章

poj 1182 食物链(种类并查集 ‘初心者’)

题目链接:http://poj.org/problem?id=1182 借着这题可以好好理解一下种类并查集,这题比较简单但挺经典的. 题意就不解释了,中问题. 关于种类并查集结局方法也是挺多的 1扩增倍数. 就是有几种关系就建立几倍数组,具体方法在这里不详细说了,这种方法有弊端 比较复杂而且内存消耗比较大如果关系比较多就容易爆掉. 2向量的方法. 这种方法要详细解说一下.这个方法好处都有啥.......(自行脑补后面的话) 这个方法的优点占用内存比较小而且比较简洁.只要找到关系就行. 下面就用方

poj 1182食物链【种类并查集】

食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 49310   Accepted: 14382 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同

POJ 1182 食物链 (种类并查集)

食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 47729   Accepted: 13895 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同

POJ 1733(边带权并查集+离散化)

Parity game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15492   Accepted: 5876 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 cont

POJ - 1182 食物链(种类并查集)

题目链接:http://poj.org/problem?id=1182 题意:三种关系,A吃B, B吃C,C吃A.给出k个句话,如果那句话和前面冲突即为假话 求假话出现的总数. 以前周赛考过一次,感觉好难,就溜了.(逃... 今天看<挑战...>看到有这道题目,感觉是时候来一发了... 因为有三种关系,扩增数组为3*N,每N个分别代表A 种类,B种类,C种类. 题目要求当D=1时,x和y为同类:D=2时,x吃y //默认x为A物种,然后当D=1时,说明y不可能是B和C物种,也就是说他们的爸爸不

POJ 1182——食物链——————【种类并查集】

食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1182 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一

POJ 1988 Cube Stacking (种类并查集)

题目地址:POJ 1988 这道题的查找合并的方法都能想的到,就是一点没想到,我一直天真的以为查询的时候,输入后能马上输出,这样的话在合并的时候就要所有的结点值都要算出来,但是经过路径压缩之后,没办法全部都处理到,如果不压缩妥妥的TLE..于是看了看网上的题解.才发现自己是多么的天真(ben,四声)..在查询的时候只要找一次跟就可以了..这样不需查询的也就没必要处理出来.反而更省时. 这题的基本思路是很好想的.另开两个数组,一个记录以此节点为根的子节点的数目(这样合并的时候只需要加另一个根的数目

poj 1733 Parity game 并查集 离散化

点击打开链接题目链接 Parity game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6249   Accepted: 2413 Description Now and then you play the following game with your friend. Your friend writes down a sequence consisting of zeroes and ones. You cho

poj 1733 Parity game【哈希+并查集】

这道题题意我不想说了,但是有一个条件必须的说,就是1-2其实是0-2这条边,3-4是2-4这条边,但是困惑了好久,其他就是哈希给他一个地址 ,然后把注解看下方 #include <stdio.h> #include <string.h> #define maxx 10001 int par[maxx]; int rank[maxx]; void init() { for(int i=0;i<=maxx;i++) { rank[i]=0; par[i]=i; } } int f

poj 2492 a bug&#39;s life 简单种类并查集

题意大致为找同性恋的虫子.... 这个比食物链要简单些.思路完全一致,利用取余操作实现关系之间的递推. 个人感觉利用向量,模和投影可能可以实现具有更加复杂关系的并查集. 1 #include<cstdio> 2 using namespace std; 3 const int MAXN=50010; 4 int fa[MAXN]; 5 int rel[MAXN]; // 0代表同类,1代表吃fa[i],2代表被吃 6 void _set(int n) 7 { 8 for(int i=1;i&l