[2016-03-18][POJ][1733][Parity game]
Posted 红洋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[2016-03-18][POJ][1733][Parity game]相关的知识,希望对你有一定的参考价值。
时间:2016-03-18 09:55:52 星期五
题目编号:[2016-03-18][POJ][1733][Parity game]
题目大意:给定若干的区间范围内的数字的和,问从哪句开始是错误的
分析:
- 带权并查集
- 区间长度高达1000000000显然不可能直接建立数组,但是发现询问只有5000次,也就是最多出现了5000*2个点,离散化就可以解决问题
- relation[i] i为区间的左端点,fa[i]为区间的右端点,relation[i]维护(i,fa[i])这段区间的和的奇偶状态,0表示偶数,1表示奇数
- f(a,b) f(b,c)表示区间的就状态,那么f(a,c) = (f(a,b) + f(b,c))%2;
#include <map>
#include <cstdio>
using namespace std;
typedef long long LL;
#define FOR(x,y,z) for(int (x)=(y);(x)<(z);++(x))
const int maxn = 5000*2 + 100;
int fa[maxn],relation[maxn];
map<LL ,int > m;
void ini(){
m.clear();
FOR(i,0,maxn) fa[i] = i;
}
int fnd(int x){
if(x == fa[x]) return x;
int tmp = fa[x];
fa[x] = fnd(fa[x]);
relation[x] = (relation[x] + relation[tmp])&1;
return fa[x];
}
int uni(int x,int y,int type){
int fax = fnd(x),fay = fnd(y);
if(fax == fay) return 0;
fa[fax] = fay;
relation[fax] = (relation[x] + relation[y] + type)&1;
return 1;
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int len,n,cur = 0,ans = 0,flg = 1;
LL u,v;
char str[10];
scanf("%d%d",&len,&n);
ini();
FOR(i,0,n){
if(flg){
scanf("%I64d%I64d%s",&u,&v,str);
--u;
if(!m.count(u)) u = m[u] = cur++;
else u = m[u];
if(!m.count(v)) v = m[v] = cur++;
else v = m[v];
int type = (str[0] == ‘o‘?1:0);
if(!uni(u,v,type)){
int t = (relation[ u ] + relation[ v ])&1;
if(t != type){
flg = 0;
continue;
}
}
++ans;
}else scanf("%*I64d%*I64d%*s");
}
printf("%d\n",ans);
return 0;
}
以上是关于[2016-03-18][POJ][1733][Parity game]的主要内容,如果未能解决你的问题,请参考以下文章