zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Balance的数学思想构造辅助函数
    1663. Smallest String With A Given Numeric Value (M)
    1680. Concatenation of Consecutive Binary Numbers (M)
    1631. Path With Minimum Effort (M)
    1437. Check If All 1's Are at Least Length K Places Away (E)
    1329. Sort the Matrix Diagonally (M)
    1657. Determine if Two Strings Are Close (M)
    1673. Find the Most Competitive Subsequence (M)
    1641. Count Sorted Vowel Strings (M)
    1679. Max Number of K-Sum Pairs (M)
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4486973.html
Copyright © 2011-2022 走看看