• poj 1733 并查集+hashmap


    题意:题目:有一个长度 已知的01串,给出多个条件,[l,r]这个区间中1的个数是奇数还是偶数,问前几个是正确的,没有矛盾

    链接:点我

    解题思路:hash离散化+并查集

    首先我们不考虑离散化:s[x]表示(root[x],x]区间1的个数的奇偶性,0-偶数,1-奇数

    每个输入区间[a,b],首先判断a-1与b的根节点是否相同

    a)如果相同表示(a-1,b]之间1的个数奇偶性已知s((a-1,b])=s[a-1]^s[b],此时只需简单判断即可

    b)如果不同,我们需要合并两个子树,我们将root较大的子树(例root[a])合并到root较小的子树(例root[b]),且此时s[root[a]]=s[a]^s[b]^s((a-1,b])

    在路径压缩的过程中s[i]=s[i]^s[root[i]],s[root[i]]为(root[root[i]], root[i]]区间内1个数的奇偶性,例(a, b]区间1的个数为偶数,(b, c]区间1的个数为奇数,(a, c]之间1的个数显然为0^1=1奇数

     1 /*
     2 POJ 1733
     3 HASH+并查集实现
     4 */
     5 #include <stdio.h>
     6 #include <algorithm>
     7 #include <iostream>
     8 #include <string.h>
     9 using namespace std;
    10 
    11 const int HASH=10007;
    12 const int MAXN=10010;
    13 
    14 struct HASHMAP
    15 {
    16     int head[HASH];
    17     int next[MAXN];
    18     int size;
    19     int state[MAXN];
    20     void init()
    21     {
    22         size=0;
    23         memset(head,-1,sizeof(head));
    24     }
    25     int push(int st)
    26     {
    27         int i,h=st%HASH;
    28         for(i=head[h];i!=-1;i=next[i])
    29            if(state[i]==st)
    30              return i;
    31         state[size]=st;
    32         next[size]=head[h];
    33         head[h]=size++;
    34         return size-1;
    35     }
    36 }hm;
    37 int F[MAXN];
    38 int val[MAXN];
    39 int find(int x)
    40 {
    41     if(F[x]==-1)return x;
    42     int tmp=find(F[x]);
    43     val[x]^=val[F[x]];
    44     return F[x]=tmp;
    45 }
    46 
    47 int main()
    48 {
    49     int n,m;
    50     int u,v;
    51     char str[20];
    52     while(scanf("%d%d",&n,&m)==2)
    53     {
    54         hm.init();
    55         memset(F,-1,sizeof(F));
    56         memset(val,0,sizeof(val));
    57         int ans=m;
    58         for(int i=0;i<m;i++)
    59         {
    60             scanf("%d%d%s",&u,&v,&str);
    61             if(u>v)swap(u,v);
    62             if(ans<m)continue;
    63 
    64             u=hm.push(u-1);
    65             v=hm.push(v);
    66             //printf("%d %d
    ",u,v);
    67 
    68             int tmp;
    69             if(str[0]=='e')tmp=0;
    70             else tmp=1;
    71             int t1=find(u);
    72             int t2=find(v);
    73 
    74             if(t1==t2)
    75             {
    76                 if(val[u]^val[v]!=tmp)ans=i;
    77             }
    78             else
    79             {
    80                 F[t2]=t1;
    81                 val[t2]=tmp^val[u]^val[v];
    82             }
    83 
    84         }
    85         printf("%d
    ",ans);
    86     }
    87     return 0;
    88 }
  • 相关阅读:
    计算机组成原理--中断系统
    操作系统--文件管理2
    操作系统--文件管理1
    操作系统--存储管理4
    操作系统--存储管理3
    操作系统--存储管理2
    操作系统--存储管理1
    有序线性表(存储结构数组)--Java实现
    【Java】之static静态方法与非static静态方法区别
    【Android Studio】之构建项目报错
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4486973.html
Copyright © 2020-2023  润新知