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 }

 

posted @ 2015-05-08 10:28  miao_a_miao  阅读(237)  评论(0编辑  收藏  举报