题目链接: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 }