POJ 1733 Parity game(种类并查集)
Posted 谦谦君子,陌上其华
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1733 Parity game(种类并查集)相关的知识,希望对你有一定的参考价值。
http://poj.org/problem?id=1733
题意:
给出一个01串,有多次询问,每次回答[l,r]这个区间内1的个数的奇偶性,但是其中有一些回答是错误的,问到第几个回答时与前面的回答是有矛盾的。
思路:
任意一个区间要么是奇要么就是偶。所有就可以用种类并查集来解决。
因为是区间,所以如果要连起来的话,每个区间的左端点需要减1。
因为n很大但是询问少,所有需要离散化处理。
下面的代码中,1表示奇,0表示偶。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 const int maxn = 2*5005; 6 7 int n,q,tot; 8 int p[maxn],re[maxn],a[maxn]; //0表示偶,1表示奇 9 10 struct node 11 { 12 int l, r; 13 char s[5]; 14 }query[maxn]; 15 16 int finds(int x) 17 { 18 if(p[x]==x) return x; 19 int tmp = p[x]; 20 p[x] = finds(p[x]); 21 re[x] = (re[x]+re[tmp])%2; 22 return p[x]; 23 } 24 25 void unions(int l,int r,int x, int y,int tmp) 26 { 27 if(x<y) 28 { 29 p[x] = y; 30 re[x] = (re[r]-re[l]+tmp+2)%2; 31 } 32 else 33 { 34 p[y] = x; 35 re[y] = (re[l] - re[r]-tmp+2)%2; 36 } 37 } 38 39 int main() 40 { 41 //freopen("in.txt","r",stdin); 42 tot = 0; 43 scanf("%d%d",&n,&q); 44 for(int i=0;i<=maxn;i++) {p[i] = i;re[i]=0;} 45 for(int i=1;i<=q;i++) 46 { 47 scanf("%d%d%s",&query[i].l,&query[i].r,query[i].s); 48 query[i].l--; 49 a[++tot] = query[i].l; 50 a[++tot] = query[i].r; 51 } 52 sort(a+1,a+tot+1); 53 int num = unique(a+1,a+tot+1)-(a+1); 54 int i; 55 for(i=1;i<=q;i++) 56 { 57 int l = lower_bound(a+1,a+num+1,query[i].l)-(a+1); 58 int r = lower_bound(a+1,a+num+1,query[i].r)-(a+1); 59 int x = finds(l); 60 int y = finds(r); 61 int tmp = 0; 62 if(query[i].s[0]==‘o‘) tmp = 1; 63 if(x==y) 64 { 65 66 if((re[l]-re[r]+2)%2!=tmp) break; 67 } 68 else 69 { 70 unions(l,r,x,y,tmp); 71 } 72 } 73 printf("%d\n",i-1); 74 return 0; 75 }
以上是关于POJ 1733 Parity game(种类并查集)的主要内容,如果未能解决你的问题,请参考以下文章