POJ1733:Parity game

浅谈并查集:https://www.cnblogs.com/AKMer/p/10360090.html

题目传送门:http://poj.org/problem?id=1733

带权并查集裸题。区间和可以由前缀和相减得到,如果区间[l,r][l,r]为奇数,那么sum[l1]sum[l1]sum[r]sum[r]奇偶性就不同,否则反之。

用并查集合并l1l1rr的同时维护一个dd数组,d[x]d[x]表示xx与祖先的奇偶性是否相同,可以直接异或求得。

时间复杂度:O(αm)O(αm)

空间复杂度:O(n)O(n)

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn=1e4+5;

char s[5];
int n,m,cnt;
int l[maxn],r[maxn],opt[maxn];
int fa[maxn],d[maxn],tmp[maxn<<1];

int read() {
	int x=0,f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
	return x*f;
}

int find(int x) {
	if(fa[x]==x)return x;
	int tmp=fa[x];
	fa[x]=find(fa[x]);
	d[x]^=d[tmp];return fa[x];
}

int main() {
	n=read(),m=read();
	for(int i=1;i<=m;i++) {
		tmp[i]=l[i]=read()-1;
		tmp[i+m]=r[i]=read();
		scanf("%s",s+1);
		if(s[1]=='e')opt[i]=0;
		else opt[i]=1;
	}
	sort(tmp+1,tmp+(m<<1)+1);
	cnt=unique(tmp+1,tmp+(m<<1)+1)-tmp-1;
	for(int i=1;i<=m;i++) {
		l[i]=lower_bound(tmp+1,tmp+cnt+1,l[i])-tmp;
		r[i]=lower_bound(tmp+1,tmp+cnt+1,r[i])-tmp;
	}
	for(int i=1;i<=cnt;i++)fa[i]=i;
	for(int i=1;i<=m;i++) {
		int p=find(l[i]),q=find(r[i]);
		if(p==q&&(d[l[i]]^d[r[i]])!=opt[i]) {
			printf("%d\n",i-1);return 0;
		}
		else if(p!=q)fa[p]=q,d[p]=opt[i]^d[l[i]]^d[r[i]];
	}
	printf("%d\n",m);
	return 0;
}
posted @   AKMer  阅读(96)  评论(0编辑  收藏  举报
编辑推荐:
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· Linux系列:如何调试 malloc 的底层源码
阅读排行:
· C# 中比较实用的关键字,基础高频面试题!
· .NET 10 Preview 2 增强了 Blazor 和.NET MAUI
· Ollama系列05:Ollama API 使用指南
· 为什么AI教师难以实现
· 如何让低于1B参数的小型语言模型实现 100% 的准确率
点击右上角即可分享
微信分享提示