Parity game
题目
有一个长度为n的序列
给出Q条限制
l,r,str str==odd 表示[l,r]区间内的数的和是奇数,否则为偶数
请你输出最小的不满足条件的编号-1(即最后一个满足的),如果全部满足,输出总数Q!
分析
算是一个带权并查集的模板题。dis[i]记录他到根结点的距离,假如a,b现在已经加入并查集了,现在要查询a,b之间的奇偶,只需要abs(dis[a]-dis[b]),然后拿此结果与当前answer进行比较就行了。不匹配,就break。
坑点:c++的取余可以是负数,在比较奇偶时加上绝对值
AC代码
#include <iostream>
#include <algorithm>
#include <map>
#include <stdio.h>
#include <string>
using namespace std;
int N,M;
map<int,int> fa,dis;
int find(int x){
if(x != fa[x]) {
int f = fa[x];
fa[x] = find(fa[x]);
dis[x] += dis[f];
}
return fa[x];
}
void join(int x,int y,int v){
int fx = find(x),fy = find(y);
if(fx != fy){
fa[fx] = fy;
dis[fx] = dis[y]+v-dis[x];
}
}
int main(){
cin>>N>>M;
int a,b,v,res =0;string s;
while(M--){
scanf("%d %d",&a,&b);b++;
if(!dis.count(a)) {
dis[a] = 0;
fa[a] = a;
}
if(!dis.count(b)) {
dis[b] = 0;
fa[b] = b;
}
cin>>s;
if(s == "even") v = 0;
else v = 1;
if(find(a) == find(b)){
if(abs((dis[a]-dis[b])%2) != v){ //注意要取绝对值
break;
}
}else{
join(a,b,v);
}
res++;
}
cout<<res<<endl;
return 0;
} 
京公网安备 11010502036488号