【带权并查集】【离散化】vijos P1112 小胖的奇偶

每个区间拆成r和l-1两个端点,若之内有偶数个1,则这两个端点对应的前缀的奇偶性必须相同,否则必须相反。

于是可以用带权并查集维护,每个结点储存其与其父节点的奇偶性是否相同,并且在路径压缩以及Union时进行分类讨论即可。

由于n太大,要对两个端点进行离散化。

#include<cstdio>
#include<algorithm>
using namespace std;
int fa[10010];
bool rel[10010];
int findroot(int x){
	if(x==fa[x]){
		return x;
	}
	int Fa=findroot(fa[x]);
	if(rel[x]==0 && rel[fa[x]]==0){
		rel[x]=0;
	}
	else if(rel[x]==0 && rel[fa[x]]==1){
		rel[x]=1;
	}
	else if(rel[x]==1 && rel[fa[x]]==0){
		rel[x]=1;
	}
	else if(rel[x]==1 && rel[fa[x]]==1){
		rel[x]=0;
	}
	return fa[x]=Fa;
}
struct Data{
	int v,p;
}t[10010];
bool cmp(const Data &a,const Data &b){
	return a.v<b.v;
}
int n,m,a[10010];
char op[5010][7];
int main(){
//	freopen("vijos1112.in","r",stdin);
	int e=0;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i){
		scanf("%d%d%s",&t[(i<<1)-1].v,&t[i<<1].v,op[i]);
		--t[(i<<1)-1].v;
		t[(i<<1)-1].p=(i<<1)-1;
		t[i<<1].p=(i<<1);
	}
	sort(t+1,t+(m<<1|1),cmp);
	a[t[1].p]=++e;
	for(int i=2;i<=(m<<1);++i){
		if(t[i].v!=t[i-1].v){
			++e;
		}
		a[t[i].p]=e;
	}
	for(int i=1;i<=e;++i){
		fa[i]=i;
	}
	for(int i=1;i<=m;++i){
		int x=a[(i<<1)-1],y=a[i<<1];
		int f1=findroot(x),f2=findroot(y);
		if(f1==f2){
			if(op[i][0]==‘o‘){
				if(rel[x]==rel[y]){
					printf("%d\n",i-1);
					return 0;
				}
			}
			else{
				if(rel[x]!=rel[y]){
					printf("%d\n",i-1);
					return 0;
				}
			}
		}
		else{
			fa[f1]=f2;
			if(op[i][0]==‘o‘){
				if(rel[x]==0 && rel[y]==0){
					rel[f1]=1;
				}
				else if(rel[x]==0 && rel[y]==1){
					rel[f1]=0;
				}
				else if(rel[x]==1 && rel[y]==0){
					rel[f1]=0;
				}
				else if(rel[x]==1 && rel[y]==1){
					rel[f1]=1;
				}
			}
			else{
				if(rel[x]==0 && rel[y]==0){
					rel[f1]=0;
				}
				else if(rel[x]==0 && rel[y]==1){
					rel[f1]=1;
				}
				else if(rel[x]==1 && rel[y]==0){
					rel[f1]=1;
				}
				else if(rel[x]==1 && rel[y]==1){
					rel[f1]=0;
				}
			}
		}
	}
	printf("%d\n",m);
	return 0;
}
时间: 2024-10-23 22:36:13

【带权并查集】【离散化】vijos P1112 小胖的奇偶的相关文章

POJ - 1733 Parity game 带权并查集+离散化

题目大意:有10E位数,每位上的数不是1就是0.现在给出第n位到第m位的1的数量的奇偶性,判断所给出的话有几句是对的 解题思路:有10E位数,肯定要离散化处理 因为有可能给出的区间是左端点等于右端点的,所以每次都把左端点的值减去1再进行处理 给出了区间的奇偶性,就要找一下是否和前面的矛盾,如果该区间的左端点的根节点和右端点的根节点是相同的,那么就可以判断是否正确了 如果根节点不同,就进行合并,合并时要注意判断是谁的根节点比较大 #include<cstdio> #include<algo

总结一下我理解的带权并查集

总结一下我理解的带权并查集 与普通并查集的区别:普通的并查集仅仅记录的是集合的关系,这个关系无非是同属一个集合或者是不在一个集合,而带权并查集是记录集合内元素的关系,而这个关系被带上了一个权值表示集合内元素之间关系的区别,例如食物链这道题,权值为0表示和根节点是同类,权值为1表示吃根节点... 用向量法来表示带权并查集 查询是否在同一个集合,或者同一个集合内的元素如何表示他们之间的关系 ??? 每个元素带一个权值用rank表示 如上图,用向量法表示则是a->root+a->b=b->ro

并查集练习2(带权并查集)

明天旅游去爬山逛庙玩,今天练一天然后早早睡觉啦~ poj1703 Find them, Catch them (带权并查集) 1 #include<cstdio> 2 const int N=1e5+1; 3 int f[N]; 4 int r[N];//表示与父节点的关系,0同类,1不同类 5 int n; 6 void init(){ 7 for(int i=1;i<=n;++i){ 8 f[i]=i; r[i]=0; 9 } 10 } 11 int fin(int x){ 12 i

poj 1733(带权并查集)

题意:有n个结点,给出了q个操作,操作是a b string表示结点a到结点b的和是奇数或偶数,输出x(前x个操作都是正确的). 题解:带权并查集经典题,因为结点可能有10,000,000,000个,所以需要离散化,不用的点就不考虑了.因为要a加到b,如果a==b无法找到各自的根节点并判断是否要合并,所以其实是mp[a - 1]到mp[b]并入集合.另外需要注意结点是有顺序的,父亲结点要大于等于子节点,这样判断才不会出错,所以合并时要考虑两个根结点的大小有不同关系式. #include <std

POJ 1773 Parity game 带权并查集

分析:带权并查集,就是维护一堆关系 然后就是带权并查集的三步 1:首先确定权值数组,sum[i]代表父节点到子节点之间的1的个数(当然路径压缩后代表到根节点的个数) 1代表是奇数个,0代表偶数个 2:设计路径压缩算法 sum[x]=(sum[x]+sum[t])%2; 3:弄清合并根节点时的操作,小的在上: 注:这个题需要离散化 #include <stdio.h> #include <string.h> #include <algorithm> using names

POJ 1733(边带权并查集+离散化)

Parity game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15492   Accepted: 5876 Description Now and then you play the following game with your friend. Your friend writes down a sequence consisting of zeroes and ones. You choose a cont

「带权并查集」奇偶游戏

奇偶游戏 原题链接:奇偶游戏 题目大意 给你N个区间,每个区间给你它含1的奇偶性,问你哪些询问逻辑上冲突 题目题解 一道带权并查集的题,让我对带权并查集有了更深入的理解,带权并查集可以分为两种(在这道题中) "边带权"并查集 "扩展域"并查集 两种方法都是思维上的不同所造成的,其中第一种解法是最常见的,第二种解法在代码实现上是最简单的,我们先来对第一种进行探究 边带权,很明显,我们要在并查集的边上进行一个储存边权的操作,我们这里用d来表示当前节点到根节点的Xor值,

hdu3038(带权并查集)

题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=3038 题意: n表示有一个长度为n的数组, 接下来有m行形如x, y, d的输入, 表示从第x,个元素到第y个元素的和为d(包括x, 和y), 问m行输入里面有几个是错误的(第一个输入是正确的); 思路: 很显然带权并查集咯,我们可以用距离的概念代替和的概念比较好理解一点,d表示x到y的和即x到y的距离; 可以用rank[x]表示x到其父亲节点的距离,  将正确的距离关系合并到并查集中

【POJ1182】 食物链 (带权并查集)

Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类. 第二种说法是"2 X Y",表示X吃Y. 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的.当一句话满足下列三条之