离散化+带权并查集

题意:长度为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建立映射

  1. #include <iostream>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <map>
  5.  
  6. /*
  7. 125ms
  8. */
  9. using namespace std;
  10. const int maxn=;
  11. int father[maxn];
  12. int val[maxn]; //val[i]表示i相对根节点的权值
  13. int n,m;
  14. map<int,int> hash_idx;
  15.  
  16. void init(){
  17. for(int i=;i<maxn;i++){
  18. father[i]=i;
  19. val[i]=;
  20. }
  21. }
  22.  
  23. int find_root(int x){
  24. if(father[x]==x)
  25. return x;
  26. int tmp=father[x];
  27. father[x]=find_root(father[x]);
  28. val[x]=val[x]^val[tmp];
  29. return father[x];
  30. }
  31. void Union(int x,int y){
  32. father[y]=x;
  33. }
  34. int main()
  35. {
  36. int a,b,c,add,x,y,fx,fy,i;
  37. char str[];
  38. scanf("%d",&n);
  39. scanf("%d",&m);
  40. init();
  41. add=;
  42. for(i=;i<=m;i++){
  43. scanf("%d%d%s",&a,&b,str);
  44. if(str[]=='o')
  45. c=;
  46. else
  47. c=;
  48. a--;
  49. //用map来离散化,如果map中还不存在关于a、b的映射,则新建映射
  50. if(hash_idx.find(a)==hash_idx.end()){
  51. hash_idx[a]=add++;
  52. }
  53. if(hash_idx.find(b)==hash_idx.end()){
  54. hash_idx[b]=add++;
  55. }
  56. x=hash_idx[a];
  57. y=hash_idx[b];
  58. fx=find_root(x);
  59. fy=find_root(y);
  60. if(fx==fy){
  61. if((val[x]^val[y])!=c){
  62. break;
  63. }
  64. }
  65. else{
  66. Union(fx,fy);
  67. val[fy]=val[x]^val[y]^c;
  68. }
  69. }
  70. printf("%d\n",i-);
  71. return ;
  72. }

2.用邻接表离散

  1. #include <iostream>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <map>
  5.  
  6. /*
  7. 47ms
  8. */
  9. using namespace std;
  10. const int maxn=;
  11. const int mod=;
  12. int father[maxn];
  13. int val[maxn]; //val[i]表示i相对根节点的权值
  14. int n,m,cnt;
  15. int head[maxn];
  16.  
  17. struct Node{
  18. int u; //即点的编号
  19. int next;
  20. }e[maxn];
  21.  
  22. //用邻接表来离散化,x的映射即为边的编号cnt。
  23. int get_hash(int x){
  24. int h=x%mod,i;
  25. for(i=head[h];i!=-;i=e[i].next){
  26. if(e[i].u==x)
  27. return i;
  28. }
  29. e[cnt].next=head[h];
  30. e[cnt].u=x;
  31. head[h]=cnt++;
  32. return cnt-;
  33. }
  34.  
  35. void init(){
  36. cnt=;
  37. memset(head,-,sizeof(head));
  38. for(int i=;i<maxn;i++){
  39. father[i]=i;
  40. val[i]=;
  41. }
  42. }
  43.  
  44. int find_root(int x){
  45. if(father[x]==x)
  46. return x;
  47. int tmp=father[x];
  48. father[x]=find_root(father[x]);
  49. val[x]=val[x]^val[tmp];
  50. return father[x];
  51. }
  52. void Union(int x,int y){
  53. father[y]=x;
  54. }
  55. int main()
  56. {
  57. int a,b,c,x,y,fx,fy,i;
  58. char str[];
  59. scanf("%d",&n);
  60. scanf("%d",&m);
  61. init();
  62. for(i=;i<=m;i++){
  63. scanf("%d%d%s",&a,&b,str);
  64. if(str[]=='o')
  65. c=;
  66. else
  67. c=;
  68. a--;
  69. //获取相应的映射,即离散的值
  70. x=get_hash(a);
  71. y=get_hash(b);
  72. fx=find_root(x);
  73. fy=find_root(y);
  74. if(fx==fy){
  75. if((val[x]^val[y])!=c){
  76. break;
  77. }
  78. }
  79. else{
  80. Union(fx,fy);
  81. val[fy]=val[x]^val[y]^c;
  82. }
  83. }
  84. printf("%d\n",i-);
  85. return ;
  86. }

POJ 1733 Parity game(离散化+带权并查集)的更多相关文章

  1. poj 1733 Parity game(带权并查集+离散化)

    题目链接:http://poj.org/problem?id=1733 题目大意:有一个很长很长含有01的字符串,长度可达1000000000,首先告诉你字符串的长度n,再给一个m,表示给你m条信息, ...

  2. POJ 1733 Parity game 【带权并查集】+【离散化】

    <题目链接> 题目大意: 一个由0,1组成的序列,每次给出一段区间的奇偶,问哪一条信息不合法. 解题分析: 我们用s[i]表示前i个数的前缀和,那么a b even意味着s[b]和s[a- ...

  3. POJ 1733 Parity game(带权并查集)

    题目链接:http://poj.org/problem?id=1733 题目大意:给你m条信息,每条信息告诉你区间l~r的1的个数是奇数还是偶数,如果后面出现信息跟前面矛盾则这条信息是错误的,问在第一 ...

  4. POJ1733:Parity Game(离散化+带权并查集)

    Parity Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12853   Accepted: 4957 题目链接 ...

  5. POJ 1988 Cube Stacking( 带权并查集 )*

    POJ 1988 Cube Stacking( 带权并查集 ) 非常棒的一道题!借鉴"找回失去的"博客 链接:传送门 题意: P次查询,每次查询有两种: M x y 将包含x的集合 ...

  6. POJ-1733 Parity game(带权并查集区间合并)

    http://poj.org/problem?id=1733 题目描述 你和你的朋友玩一个游戏.你的朋友写下来一连串的0或者1.你选择一个连续的子序列然后问他,这个子序列包含1的个数是奇数还是偶数.你 ...

  7. Poj1733 Parity Game(带权并查集)

    题面 Poj 题解 反正只要你判断是否满足区间的奇偶性,假设每一位要么是\(1\)要么是\(0\)好了. 假设有\(S\)的前缀和为\(sum[]\),则有: 若\(S[l...r]\)中有奇数个\( ...

  8. POJ1733 Parity game 【带权并查集】*

    POJ1733 Parity game Description Now and then you play the following game with your friend. Your frie ...

  9. AcWing:239. 奇偶游戏(前缀和 + 离散化 + 带权并查集 + 异或性质 or 扩展域并查集 + 离散化)

    小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...

随机推荐

  1. nyoj71--独木舟上的旅行

    描述 进行一次独木舟的旅行活动,独木舟可以在港口租到,并且之间没有区别.一条独木舟最多只能乘坐两个人,且乘客的总重量不能超过独木舟的最大承载量.我们要尽量减少这次活动中的花销,所以要找出可以安置所有旅 ...

  2. 南阳理工ACM——106背包问题

    描述: 现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1<=v,w<=10):如果给你一个背包它能容纳的重量为m(10<=m<=20),你 ...

  3. POJ 1285 确定比赛名次

    Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委 ...

  4. 枪击手机屏幕应用android源码

    这款是作者最新的一款应用源码,枪击手机屏幕应用源码,该应用源码比较完整的,应用目前已经上线了一些应用商店了,大家想更深入的了解,可以到一些应用商店下载吧,直接搜索相关的关键字就可以搜到了,或者在下面有 ...

  5. 【风马一族_Python】 更替pip的版本

    替换电脑上python中的pip的版本 例子: 下载的文件:pip-8.1.1-py2.py3-none-any.whl 下载地址:https://pypi.python.org/pypi/pip/# ...

  6. PHP 正则表达式替换一部分内容

    preg_replace('/&topic=(.*?)&type=/',"&topic={$data['topic']}&type=",$postF ...

  7. zedboard之GPIO驱动(从FPGA一直到LINUX应用)

    1 EDK 大家知道我们在EDK中建立GPIO然后倒出到SDK中,在SDK中可以用C语言操作外设GPIO,但是这还是裸机程序,没有用到LINUX.本文将记录从FPGA  EDK生成GPIO一直到导入S ...

  8. 封装鼠标滚轮事件_mousewheel

    function mousewheel(obj,fn){ obj.onmousewheel===null ? obj.onmousewheel=fun : obj.addEventListener(' ...

  9. 前端自动化构建工具——gulp

    gulp是基于流的前端自动化构建工具. 一.环境配置 gulp是基于nodejs的,所以没有 nodejs 环境的要先去安装好 然后给系统配上gulp环境 npm install -g gulp 再到 ...

  10. 《PHP和MySQL Web开发》精彩的地方收录

    1.用SESSION来做的购物车,做成数组,用isbn对应书的数量作为二维数组保存 $new GET传值加入购物车,submit是修改数量,提交后的表单,通过历遍原来的数组,对应isbn修改最新的数量 ...