POJ 1733 Parity game(离散化+带权并查集)
离散化+带权并查集
题意:长度为n的0和1组成的字符串,然后问第L和R位置之间有奇数个1还是偶数个1. 根据这些回答, 判断第几个是错误(和之前有矛盾)的。
思路:此题同HDU 3038 差不多,询问L~R之间的1的奇偶性,相当于HDU 3038 的L~R之间的和。所以合并的时候,合并L-1和R(L-1为父亲)。 则R相对L-1的权值(不包括L-1)即为L~R之间1的个数(0代表有偶数个1,1代表有奇数个1).
之所以为什么合并的是L-1和R,举个例子: 1 2 even 3 4 odd 首先合并0、2,2相对0的权值为0,接着合并2、4,4相对2的权值为1。 那么之后在查找4的根节点时,会更新4与根节点的关系,则4相对0的权值为:(4相对2的权值+2相对0的权值)%2,也可以用异或来更新。 因为权值不包括父节点在内(即4相对2的不包括2,2相对0的不包括0),所以结果就是1、2、3、4中1的个数的奇偶性。
每次读取数据时,先查找L-1和R的根节点。
1:如果相等,均为f,则判断L~R的1的奇偶是否与数据c相同,即(val[L-1]-val[R]+2)%2是否等于c,也可以用异或val[L-1]^val[R];
2:如果不同,则合并。L-1的根节点为fx,R的根节点为fy,则fy相对fx的权值val[fy]=(c+val[L-1]-val[R]+2)%2, 或者val[fy]=c^val[L-1]^val[R].
当找到矛盾时,直接退出即可,接下来的数据不需要管它。
由于n的数据很大,10亿,但查询只有5000次,也就是最多出现1万个数,因此采用离散化,不影响结果。
附两种离散的方法:
1:用map建立映射
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <map> /*
125ms
*/
using namespace std;
const int maxn=;
int father[maxn];
int val[maxn]; //val[i]表示i相对根节点的权值
int n,m;
map<int,int> hash_idx; void init(){
for(int i=;i<maxn;i++){
father[i]=i;
val[i]=;
}
} int find_root(int x){
if(father[x]==x)
return x;
int tmp=father[x];
father[x]=find_root(father[x]);
val[x]=val[x]^val[tmp];
return father[x];
}
void Union(int x,int y){
father[y]=x;
}
int main()
{
int a,b,c,add,x,y,fx,fy,i;
char str[];
scanf("%d",&n);
scanf("%d",&m);
init();
add=;
for(i=;i<=m;i++){
scanf("%d%d%s",&a,&b,str);
if(str[]=='o')
c=;
else
c=;
a--;
//用map来离散化,如果map中还不存在关于a、b的映射,则新建映射
if(hash_idx.find(a)==hash_idx.end()){
hash_idx[a]=add++;
}
if(hash_idx.find(b)==hash_idx.end()){
hash_idx[b]=add++;
}
x=hash_idx[a];
y=hash_idx[b];
fx=find_root(x);
fy=find_root(y);
if(fx==fy){
if((val[x]^val[y])!=c){
break;
}
}
else{
Union(fx,fy);
val[fy]=val[x]^val[y]^c;
}
}
printf("%d\n",i-);
return ;
}
2.用邻接表离散
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <map> /*
47ms
*/
using namespace std;
const int maxn=;
const int mod=;
int father[maxn];
int val[maxn]; //val[i]表示i相对根节点的权值
int n,m,cnt;
int head[maxn]; struct Node{
int u; //即点的编号
int next;
}e[maxn]; //用邻接表来离散化,x的映射即为边的编号cnt。
int get_hash(int x){
int h=x%mod,i;
for(i=head[h];i!=-;i=e[i].next){
if(e[i].u==x)
return i;
}
e[cnt].next=head[h];
e[cnt].u=x;
head[h]=cnt++;
return cnt-;
} void init(){
cnt=;
memset(head,-,sizeof(head));
for(int i=;i<maxn;i++){
father[i]=i;
val[i]=;
}
} int find_root(int x){
if(father[x]==x)
return x;
int tmp=father[x];
father[x]=find_root(father[x]);
val[x]=val[x]^val[tmp];
return father[x];
}
void Union(int x,int y){
father[y]=x;
}
int main()
{
int a,b,c,x,y,fx,fy,i;
char str[];
scanf("%d",&n);
scanf("%d",&m);
init();
for(i=;i<=m;i++){
scanf("%d%d%s",&a,&b,str);
if(str[]=='o')
c=;
else
c=;
a--;
//获取相应的映射,即离散的值
x=get_hash(a);
y=get_hash(b);
fx=find_root(x);
fy=find_root(y);
if(fx==fy){
if((val[x]^val[y])!=c){
break;
}
}
else{
Union(fx,fy);
val[fy]=val[x]^val[y]^c;
}
}
printf("%d\n",i-);
return ;
}
POJ 1733 Parity game(离散化+带权并查集)的更多相关文章
- poj 1733 Parity game(带权并查集+离散化)
题目链接:http://poj.org/problem?id=1733 题目大意:有一个很长很长含有01的字符串,长度可达1000000000,首先告诉你字符串的长度n,再给一个m,表示给你m条信息, ...
- POJ 1733 Parity game 【带权并查集】+【离散化】
<题目链接> 题目大意: 一个由0,1组成的序列,每次给出一段区间的奇偶,问哪一条信息不合法. 解题分析: 我们用s[i]表示前i个数的前缀和,那么a b even意味着s[b]和s[a- ...
- POJ 1733 Parity game(带权并查集)
题目链接:http://poj.org/problem?id=1733 题目大意:给你m条信息,每条信息告诉你区间l~r的1的个数是奇数还是偶数,如果后面出现信息跟前面矛盾则这条信息是错误的,问在第一 ...
- POJ1733:Parity Game(离散化+带权并查集)
Parity Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12853 Accepted: 4957 题目链接 ...
- POJ 1988 Cube Stacking( 带权并查集 )*
POJ 1988 Cube Stacking( 带权并查集 ) 非常棒的一道题!借鉴"找回失去的"博客 链接:传送门 题意: P次查询,每次查询有两种: M x y 将包含x的集合 ...
- POJ-1733 Parity game(带权并查集区间合并)
http://poj.org/problem?id=1733 题目描述 你和你的朋友玩一个游戏.你的朋友写下来一连串的0或者1.你选择一个连续的子序列然后问他,这个子序列包含1的个数是奇数还是偶数.你 ...
- Poj1733 Parity Game(带权并查集)
题面 Poj 题解 反正只要你判断是否满足区间的奇偶性,假设每一位要么是\(1\)要么是\(0\)好了. 假设有\(S\)的前缀和为\(sum[]\),则有: 若\(S[l...r]\)中有奇数个\( ...
- POJ1733 Parity game 【带权并查集】*
POJ1733 Parity game Description Now and then you play the following game with your friend. Your frie ...
- AcWing:239. 奇偶游戏(前缀和 + 离散化 + 带权并查集 + 异或性质 or 扩展域并查集 + 离散化)
小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...
随机推荐
- OpenGL第18,19,20讲小结
18讲是通过调用库函数画一些简单的二次几何体,比如球体.圆锥体.圆盘等等. 19讲简单的讲了下粒子系统.其实就是三角形贴上星星的纹理,通过启用混合(GL_BLEND)来达到一种动态的粒子效果.通过修改 ...
- 真正明白C语言二级指针(转载)
指针是C语言的灵魂,我想对于一级指针大家应该都很熟悉,也经常用到:比如说对于字符串的处理,函数参数的“值,结果传递”等,对于二级指针或者多级指针,我想理解起来也是比较容易的,比如二级指针就是指向指针的 ...
- 3月7日 Maximum Subarray
间隔2天,继续开始写LeetCodeOj. 原题: Maximum Subarray 其实这题很早就看了,也知道怎么做,在<编程珠玑>中有提到,求最大连续子序列,其实只需要O(n)的复杂度 ...
- mysql 基础知识
Mysql 远程登录及常用命令 第一招.mysql服务的启动和停止 net stop mysql net start mysql 第二招.登陆mysql 语法如下: mysql -u用户名 -p用户密 ...
- 配置drbd高可用集群
前期准备: 同步时间 (两个节点) 节点一(172.16.21.6) [root@stu21 heartbeat2]# ntpdate 172.16.0.1 31 Dec 20:59:25 ntpda ...
- 可以支持jQuery1.10.1 的 fancybox 1.3.4, 並現在type為Ajax時,也可以定義窗口的大小。
官網上的 fancybox 1.3.4 太老了,不支持jQuery1.10.1,改動了一下源碼,現在可以支持了. type為Ajax時,也可以定義窗口的大小. $("#ajaxlink&qu ...
- js设计模式(7)---装饰者模式
0.前言 下午做事效率很低,无精打采的,整个脑子就跟浆糊一样,看看时间一点点流去,心中只能无可奈何,哎,码农的激情难道就这么容易熄灭吗? 1.该模式的使用情况 假如我们想给对象增加功能,但是又不想修改 ...
- CenterOS中安装Redis及开机启动设置
Redis安装 从官方下载最新Redis进行安装,官网地址:http://redis.io/download $ wget http://download.redis.io/releases/redi ...
- Mongodb Java Driver 参数配置解析
要正确使用Mongodb Java Driver,MongoClientOptions参数配置对数据库访问的并发性能影响极大. connectionsPerHost:与目标数据库能够建立的最大conn ...
- php获取系统信息的方法
php获取系统信息的方法. 用 getenv函数进行处理: <?php $root = getenv('DOCUMENT_ROOT'); ////服务器文档根目录 $port = getenv( ...