zoukankan      html  css  js  c++  java
  • POJ 1733 Parity game(种类并查集)

    http://poj.org/problem?id=1733

    题意:

    给出一个01串,有多次询问,每次回答[l,r]这个区间内1的个数的奇偶性,但是其中有一些回答是错误的,问到第几个回答时与前面的回答是有矛盾的。

    思路:

    任意一个区间要么是奇要么就是偶。所有就可以用种类并查集来解决。

    因为是区间,所以如果要连起来的话,每个区间的左端点需要减1。

    因为n很大但是询问少,所有需要离散化处理。

    下面的代码中,1表示奇,0表示偶。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 using namespace std;
     5 const int maxn = 2*5005;
     6 
     7 int n,q,tot;
     8 int p[maxn],re[maxn],a[maxn];  //0表示偶,1表示奇
     9 
    10 struct node
    11 {
    12     int l, r;
    13     char s[5];
    14 }query[maxn];
    15 
    16 int finds(int x)
    17 {
    18     if(p[x]==x)  return x;
    19     int tmp = p[x];
    20     p[x] = finds(p[x]);
    21     re[x] = (re[x]+re[tmp])%2;
    22     return p[x];
    23 }
    24 
    25 void unions(int l,int r,int x, int y,int tmp)
    26 {
    27     if(x<y)
    28     {
    29         p[x] = y;
    30         re[x] = (re[r]-re[l]+tmp+2)%2;
    31     }
    32     else
    33     {
    34         p[y] = x;
    35         re[y] = (re[l] - re[r]-tmp+2)%2;
    36     }
    37 }
    38 
    39 int main()
    40 {
    41     //freopen("in.txt","r",stdin);
    42     tot = 0;
    43     scanf("%d%d",&n,&q);
    44     for(int i=0;i<=maxn;i++)  {p[i] = i;re[i]=0;}
    45     for(int i=1;i<=q;i++)
    46     {
    47         scanf("%d%d%s",&query[i].l,&query[i].r,query[i].s);
    48         query[i].l--;
    49         a[++tot] = query[i].l;
    50         a[++tot] = query[i].r;
    51     }
    52     sort(a+1,a+tot+1);
    53     int num = unique(a+1,a+tot+1)-(a+1);
    54     int i;
    55     for(i=1;i<=q;i++)
    56     {
    57         int l = lower_bound(a+1,a+num+1,query[i].l)-(a+1);
    58         int r = lower_bound(a+1,a+num+1,query[i].r)-(a+1);
    59         int x = finds(l);
    60         int y = finds(r);
    61         int tmp = 0;
    62         if(query[i].s[0]=='o')   tmp = 1;
    63         if(x==y)
    64         {
    65 
    66             if((re[l]-re[r]+2)%2!=tmp)  break;
    67         }
    68         else
    69         {
    70             unions(l,r,x,y,tmp);
    71         }
    72     }
    73     printf("%d
    ",i-1);
    74     return 0;
    75 }
  • 相关阅读:
    Linux查看日志常用命令
    linux(centos)下安装PHP的PDO扩展
    TP thinkphp 权限管理 权限认证 功能
    mysql优化(三)–explain分析sql语句执行效率
    阿里云服务器Centos7成为挖矿肉鸡被挖矿imWBR1耗尽CPU
    Asp.net导入Excel并读取数据
    定义显式类型转换和隐式类型转换
    C# 对象与引用变量
    C# ref参数
    C# 字段与属性的区别
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7881467.html
Copyright © 2011-2022 走看看