首先考虑四个格子异或值为1。

然后(重点)发现每个格子的值只和最上面,最左边,和(1,1)的格子的颜色有关。

枚举(1,1)的颜色,联立方程,可以将未知数减少,那么并查集可做。

最后算答案的时候,有些连通块颜色确定,有些不确定,不确定的*2即可。

这题要注意细节!其实一开始的思路最不好想。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define maxn 1000500
  6. #define mod 1000000000
  7. using namespace std;
  8. struct pnt
  9. {
  10. int x,y,c;
  11. }p[maxn];
  12. int n,m,k,fath[maxn<<],dis[maxn<<],val[maxn<<],flag=-,cnt[maxn<<];
  13. void reset()
  14. {
  15. for (int i=;i<=(n-)+(m-);i++)
  16. {
  17. fath[i]=i;
  18. dis[i]=;
  19. val[i]=-;
  20. cnt[i]=;
  21. }
  22. }
  23. int getfather(int x)
  24. {
  25. if (x==fath[x]) return fath[x];
  26. if (val[x]!=-)
  27. {
  28. if ((val[fath[x]]!=-) && (val[fath[x]]!=(val[x]^dis[x])))
  29. return -;
  30. val[fath[x]]=val[x]^dis[x];
  31. }
  32. int ret=getfather(fath[x]);
  33. dis[x]^=dis[fath[x]];
  34. fath[x]=ret;
  35. return fath[x];
  36. }
  37. int f_pow(int a,int b)
  38. {
  39. int base=a,ans=;
  40. while (b)
  41. {
  42. if (b&) ans=(ans*base)%mod;
  43. base=(base*base)%mod;
  44. b>>=;
  45. }
  46. return ans%mod;
  47. }
  48. int gets(int r)
  49. {
  50. int ans=;
  51. if (flag==-r) return ;
  52. reset();
  53. for (int i=;i<=k;i++)
  54. {
  55. if ((p[i].x==) && (p[i].y==))
  56. {
  57. if (p[i].c!=r) return ;
  58. }
  59. else if ((p[i].x==) && (p[i].y!=)) {if ((val[n+p[i].y-]!=p[i].c) && (val[n+p[i].y-]!=-)) return ;val[n+p[i].y-]=p[i].c;}
  60. else if ((p[i].x!=) && (p[i].y==)) {if ((val[p[i].x-]!=p[i].c) && (val[p[i].x-]!=-)) return ;val[p[i].x-]=p[i].c;}
  61. else
  62. {
  63. int x=p[i].x-,y=n+p[i].y-;
  64. int f1=getfather(x),f2=getfather(y);
  65. if ((f1==-) || (f2==-)) return ;
  66. if (f1==f2)
  67. {
  68. int ret=dis[x]^dis[y]^r;
  69. if ((p[i].x%==) && (p[i].y%==)) ret^=;
  70. if (ret!=p[i].c) return ;
  71. }
  72. else
  73. {
  74. int ret=p[i].c^dis[x]^dis[y]^r;
  75. if ((p[i].x%==) && (p[i].y%==)) ret^=;
  76. if ((val[f1]!=-) && (val[f2]!=-))
  77. {
  78. if ((val[f1]^ret)!=val[f2]) return ;
  79. }
  80. else if ((val[f1]==-) && (val[f2]!=-)) {fath[f1]=f2;dis[f1]=ret;}
  81. else if ((val[f1]!=-) && (val[f2]==-)) {fath[f1]=f2;dis[f1]=ret;val[f2]=val[f1]^ret;}
  82. else {fath[f1]=f2;dis[f1]=ret;}
  83. }
  84. }
  85. }
  86. for (int i=;i<=(n-)+(m-);i++)
  87. {
  88. int ret=getfather(i);
  89. if (ret==-) return ;
  90. cnt[ret]++;
  91. }
  92. for (int i=;i<=(n-)+(m-);i++)
  93. {
  94. if ((fath[i]==i) && (val[i]==-))
  95. ans=(ans*)%mod;
  96. }
  97. return ans%mod;
  98. }
  99. int main()
  100. {
  101. scanf("%d%d%d",&n,&m,&k);
  102. for (int i=;i<=k;i++)
  103. {
  104. scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].c);
  105. if ((p[i].x==) && (p[i].y==)) flag=p[i].c;
  106. }
  107. printf("%d\n",(gets()+gets())%mod);
  108. return ;
  109. }

BZOJ 2303 方格染色的更多相关文章

  1. BZOJ 2303 方格染色(带权并查集)

    要使得每个2*2的矩形有奇数个红色,如果我们把红色记为1,蓝色记为0,那么我们得到了这2*2的矩形里的数字异或和为1. 对于每个方格则有a(i,j)^a(i-1,j)^a(i,j-1)^a(i-1,j ...

  2. [BZOJ2303][Apio2011]方格染色

    [BZOJ2303][Apio2011]方格染色 试题描述 Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好,他们想要表格中每个2 × ...

  3. BZOJ_2303_[Apio2011]方格染色 _并查集

    BZOJ_2303_[Apio2011]方格染色 _并查集 Description Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好, ...

  4. BZOJ 5306 [HAOI2018] 染色

    BZOJ 5306 [HAOI2018] 染色 首先,求出$N$个位置,出现次数恰好为$S$的颜色至少有$K$种. 方案数显然为$a_i=\frac{n!\times (m-i)^{m-i\times ...

  5. bzoj 2303: [Apio2011]方格染色

    传送门 Description Sam和他的妹妹Sara有一个包含n × m个方格的表格.她们想要将其的每个方格都染成红色或蓝色.出于个人喜好,他们想要表格中每个2 × 2的方形区域都包含奇数个(1 ...

  6. BZOJ 2303: [Apio2011]方格染色 题解

    题目大意: 有n*m的方格,中间的数要么是1,要么是0,要求任意2*2的方格中的数异或和为1.已知一部分格子中的数,求合法的填数的方案数. 思路: 由题意得:a[i][j]^a[i][j+1]^a[i ...

  7. BZOJ 2303: [Apio2011]方格染色 [并查集 数学!]

    题意: $n*m:n,m \le 10^6$的网格,每个$2 \times 2$的方格必须有1个或3个涂成红色,其余涂成蓝色 有一些方格已经有颜色 求方案数 太神了!!!花我三节课 首先想了一下只有两 ...

  8. 【bzoj 2303】【Apio2011】方格染色

    题目: http://www.lydsy.com/JudgeOnline/problem.php?id=2303 题解: 很神奇的思路,膜一发大佬http://www.cnblogs.com/HHsh ...

  9. bzoj 2303: [Apio2011]方格染色【并查集】

    画图可知,每一行的状态转移到下一行只有两种:奇数列不变,偶数列^1:偶数列不变,奇数列^1 所以同一行相邻的变革染色格子要放到同一个并查集里,表示这个联通块里的列是联动的 最后统计下联通块数(不包括第 ...

随机推荐

  1. yum install 与 yum groupinstall 的区别

    原文:http://blog.51yip.com/linux/1171.html yum 提供二种安装软件的方式 1,yum install 它安装单个软件,以及这个软件的依赖关系 2,yum gro ...

  2. 7 天玩转 ASP.NET MVC — 第 6 天

    目录 第 1 天 第 2 天 第 3 天 第 4 天 第 5 天 第 6 天 第 7 天 0. 前言 欢迎来到第六天的 MVC 系列学习中.希望你在阅读此篇文章的时候,已经学习了前五天的内容,这也是第 ...

  3. delphi的socket通讯 多个客户端 (转)

    ClientSocket组件为客户端组件.它是通信的请求方,也就是说,它是主动地与服务器端建立连接. ServerSocket组件为服务器端组件.它是通信的响应方,也就是说,它的动作是监听以及被动接受 ...

  4. x64的调用约定

    在设计调用约定时,x64 体系结构利用机会清除了现有 Win32 调用约定(如 __stdcall.__cdecl.__fastcall._thiscall 等)的混乱.在 Win64 中,只有一个本 ...

  5. java反射机制浅谈

    一.Java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...

  6. poj3415 Common Substrings(后缀数组,单调栈 | 后缀自动机)

    [题目链接] http://poj.org/problem?id=3415 [题意] A与B长度至少为k的公共子串个数. [思路] 基本思想是将AB各个后缀的lcp-k+1的值求和.首先将两个字符串拼 ...

  7. 好玩的算法(JS版)

    1.字符串反转 'cba'.split('').reverse().join(''); 2.在数组最后一位添加一项 array[array.length]=(new value);

  8. 网络安装之Redhat衍生版

    GNU/Linux开源,这个意义实在是非常的广泛,目前在distrowatch上表现活跃的300个发行版代表了GNU/Linux的主流,然而细心的Linux爱好者会发现CentOS-based dis ...

  9. jqGrid中实现radiobutton的两种做法

    http://blog.sina.com.cn/s/blog_4f925fc30102e27j.html   jqGrid中实现radiobutton的两种做法 ------------------- ...

  10. 使用yum安装CDH Hadoop集群

    使用yum安装CDH Hadoop集群 2013.04.06 Update: 2014.07.21 添加 lzo 的安装 2014.05.20 修改cdh4为cdh5进行安装. 2014.10.22  ...