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还是偶数个 ...
随机推荐
- nyoj71--独木舟上的旅行
描述 进行一次独木舟的旅行活动,独木舟可以在港口租到,并且之间没有区别.一条独木舟最多只能乘坐两个人,且乘客的总重量不能超过独木舟的最大承载量.我们要尽量减少这次活动中的花销,所以要找出可以安置所有旅 ...
- 南阳理工ACM——106背包问题
描述: 现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1<=v,w<=10):如果给你一个背包它能容纳的重量为m(10<=m<=20),你 ...
- POJ 1285 确定比赛名次
Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委 ...
- 枪击手机屏幕应用android源码
这款是作者最新的一款应用源码,枪击手机屏幕应用源码,该应用源码比较完整的,应用目前已经上线了一些应用商店了,大家想更深入的了解,可以到一些应用商店下载吧,直接搜索相关的关键字就可以搜到了,或者在下面有 ...
- 【风马一族_Python】 更替pip的版本
替换电脑上python中的pip的版本 例子: 下载的文件:pip-8.1.1-py2.py3-none-any.whl 下载地址:https://pypi.python.org/pypi/pip/# ...
- PHP 正则表达式替换一部分内容
preg_replace('/&topic=(.*?)&type=/',"&topic={$data['topic']}&type=",$postF ...
- zedboard之GPIO驱动(从FPGA一直到LINUX应用)
1 EDK 大家知道我们在EDK中建立GPIO然后倒出到SDK中,在SDK中可以用C语言操作外设GPIO,但是这还是裸机程序,没有用到LINUX.本文将记录从FPGA EDK生成GPIO一直到导入S ...
- 封装鼠标滚轮事件_mousewheel
function mousewheel(obj,fn){ obj.onmousewheel===null ? obj.onmousewheel=fun : obj.addEventListener(' ...
- 前端自动化构建工具——gulp
gulp是基于流的前端自动化构建工具. 一.环境配置 gulp是基于nodejs的,所以没有 nodejs 环境的要先去安装好 然后给系统配上gulp环境 npm install -g gulp 再到 ...
- 《PHP和MySQL Web开发》精彩的地方收录
1.用SESSION来做的购物车,做成数组,用isbn对应书的数量作为二维数组保存 $new GET传值加入购物车,submit是修改数量,提交后的表单,通过历遍原来的数组,对应isbn修改最新的数量 ...