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\n",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\n",ans);

86     }

87     return 0;

88 }

 

你可能感兴趣的:(HashMap)