POJ 1733 Parity game(带权并查集)

题目链接:http://poj.org/problem?id=1733

题目大意:给你m条信息,每条信息告诉你区间l~r的1的个数是奇数还是偶数,如果后面出现信息跟前面矛盾则这条信息是错误的,问在第一条错误信息之前的正确信息数。

解题思路:对于l~r之间的1的个数的奇偶性,其实可以理解成r比l-1多的1的个数的奇偶,这样刚好可以跟前面一段区间连起来。分两个种类,奇数1,偶数0,同样满足0->1>0的关系像食物链一样。跟How Many Answers Are Wrong差不多。

代码:

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #include<set>
10 #include<map>
11 #include<stack>
12 #include<string>
13 #define LC(a) (a<<1)
14 #define RC(a) (a<<1|1)
15 #define MID(a,b) ((a+b)>>1)
16 using namespace std;
17 typedef long long LL;
18 const int INF=0x3f3f3f3f;
19 const int N=2e4+5;
20 
21 int root[N],val[N];
22 
23 struct node{
24     int l,r,cla;
25 }arr[N];
26 int X[N];
27 
28 int find(int x){
29     if(root[x]==x)
30         return x;
31     int tmp=find(root[x]);
32     val[x]=(val[x]+val[root[x]])%2;
33     return root[x]=tmp;
34 }
35 
36 int bin_search(int l,int r,int x){
37     while(l<=r){
38         int mid=(l+r)/2;
39         if(X[mid]==x)
40             return mid;
41         else if(X[mid]<x)
42             l=mid+1;
43         else
44             r=mid-1;
45     }
46     return -1;
47 }
48 
49 int main(){
50     int n,m;
51     while(~scanf("%d",&n)){
52         scanf("%d",&m);
53         int m1=0,m2=1,ans=0;
54         memset(val,0,sizeof(val));
55         for(int i=1;i<=m;i++){
56             char s[6];
57             scanf("%d%d%s",&arr[i].l,&arr[i].r,s);
58             if(s[0]=='e')
59                 arr[i].cla=0;
60             else
61                 arr[i].cla=1;
62             X[++m1]=arr[i].l;
63             X[++m1]=arr[i].r;
64         }
65         //去重
66         sort(X+1,X+1+m1);
67         for(int i=2;i<=m1;i++){
68             if(X[i]!=X[i-1])
69                 X[++m2]=X[i];
70         }
71         for(int i=0;i<=m2;i++){
72             root[i]=i;
73         }
74         for(int i=1;i<=m;i++){
75             int l=bin_search(1,m2,arr[i].l)-1;
76             int r=bin_search(1,m2,arr[i].r);
77             int c=arr[i].cla;
78             int t1=find(l);
79             int t2=find(r);
80             if(t1==t2){
81                 if((val[l]+c)%2!=val[r]){
82                     ans=i-1;
83                     break;
84                 }
85             }
86             else{
87                 root[t2]=t1;
88                 val[t2]=(val[l]-val[r]+c+2)%2;
89             }
90         }
91         if(!ans)
92             ans=m;
93         printf("%d
",ans);
94     }
95     return 0;
96 }

 

原文地址:https://www.cnblogs.com/fu3638/p/7677579.html