【题解】P3631 [APIO2011]方格染色
很有意思的一道题,所以单独拿出来了。
完整分享看 这里
题目链接
luogu
题意
有一个包含 \(n \times m\) 个方格的表格。要将其中的每个方格都染成红色或蓝色。表格中每个 \(2 \times 2\) 的方形区域都包含奇数个( \(1\) 个或 \(3\) 个)红色方格。例如,下面是一个合法的表格染色方案(R 代表红色,B 代表蓝色):
B B R B R
R B B B B
R R B R B
表格中的一些方格已经染上了颜色.求给剩下的表格染色,使得符合要求的方案数。
思路
每天一道压轴好题。 其实这题跟并查集没啥关系,只是用来维护而已
题意可以简化为:在 \(n\times m\) 的矩阵中放 01,k 个格子已经放好了,要放满,且每个 \(2\times 2\) 的格子中有奇数个1.
由题意可知,任意四个格子(二乘二)的异或值为 1,不断异或相邻的两个“矩形”的异或式子 (如:\(A\oplus B\oplus C\oplus D=C\oplus D\oplus E\oplus F=E\oplus F\oplus G\oplus H=1\),选取相邻的式子得到 \(A\oplus B\oplus E\oplus F=0,A\oplus B\oplus G\oplus H=0\) )
由这个思路推广,设 \(A(1,1),B(2,1),C(1,j),D(i,1)\)
- \(C,D\) 在奇数列上, \(A\oplus B\oplus C\oplus D=0,E\oplus F\oplus G\oplus H=0,=> A\oplus C\oplus F\oplus H=0,A\oplus H=C\oplus F.\)
- \(C,D\) 在偶数列上。\(A\oplus B\oplus C\oplus D=1,E\oplus F\oplus G\oplus H=1.\) 此时,当 \(H\) 在偶数行,\(1\oplus A\oplus H=C\oplus F\) ;如果在奇数行,则有 \(A\oplus H=C\oplus F.\)
综上所述,对于任意 \(H(i,j):\)
如果 \(i|2,j|2\) ,那么 \(1\oplus (1,1)\oplus (i,j)=(1,j)\oplus (i,1)\) ;否则 \((1,1)\oplus (i,j)=(1,j)\oplus (i,1)\)
这样就转化为对 \((1,j),(i,1)\) 的约束。如果 \((1,1)\) 没有给出,那么就要枚举两种情况。
用并查集维护。\(x\oplus y=0\) 时,合并 \((x,y),(x',y')\) ;否则合并 \((x,y'),(x',y)\)。无解特判就是 \(x,x'\in S\) (属于同一个集合)
合并完成之后得到连通块个数 \(sum\) ,枚举所有已知点(注意 \((1,1)\) 不算),去掉他们的连通块,剩下的就是未知个数,\(2^{sum'}\) 即为方案。把 \((1,1)\) 的两种情况相加即可。
注意:此题由于有虚点( \(x',y'\) ),所以空间要两倍。
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9,N=2e5+10;
int n,m,k,x[N],y[N],z[N],fa[N],g[N];
ll power( ll a,ll b )
{
ll res=1;
for ( ; b; b>>=1,a=a*a%mod )
if ( b&1 ) res=res*a%mod;
return res;
}
int find( int x )
{
if ( x==fa[x] ) return x;
int fat=find( fa[x] ); g[x]^=g[fa[x]];
return fa[x]=fat;
}
int calc( int opt )
{
for ( int i=1; i<=n+m; i++ )
fa[i]=i,g[i]=0;
fa[n+1]=1;
if ( opt==1 )
for ( int i=1; i<=k; i++ )
if ( x[i]>1 && y[i]>1 ) z[i]^=1;
for ( int i=1; i<=k; i++ )
{
int x=:: x[i],y=:: y[i],z=:: z[i];
if ( x!=1 || y!=1 )
{
int fx=find(x),fy=find(y+n),ty=g[x]^g[n+y]^z;
if ( fx!=fy ) fa[fy]=fx,g[fy]=ty;
else if ( ty ) return 0;
}
}
int res=0;
for ( int i=1; i<=n+m; i++ )
if ( i==find(i) ) res++;
return power( 2,res-1 );
}
int main()
{
scanf( "%d%d%d",&n,&m,&k );
int flag=-1;
for ( int i=1; i<=k; i++ )
{
scanf( "%d%d%d",&x[i],&y[i],&z[i] );
if ( (!(x[i]&1)) && (!(y[i]&1)) ) z[i]^=1;
if ( x[i]==1 && y[i]==1 ) flag=z[i];
}
if ( flag!=-1 ) printf( "%d\n",calc( flag ) );
else printf( "%d\n",(calc(0)+calc(1))%mod );
}
【题解】P3631 [APIO2011]方格染色的更多相关文章
- [BZOJ2303][Apio2011]方格染色
[BZOJ2303][Apio2011]方格染色 试题描述 Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好,他们想要表格中每个2 × ...
- BZOJ_2303_[Apio2011]方格染色 _并查集
BZOJ_2303_[Apio2011]方格染色 _并查集 Description Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好, ...
- BZOJ 2303: [Apio2011]方格染色 题解
题目大意: 有n*m的方格,中间的数要么是1,要么是0,要求任意2*2的方格中的数异或和为1.已知一部分格子中的数,求合法的填数的方案数. 思路: 由题意得:a[i][j]^a[i][j+1]^a[i ...
- bzoj 2303: [Apio2011]方格染色
传送门 Description Sam和他的妹妹Sara有一个包含n × m个方格的表格.她们想要将其的每个方格都染成红色或蓝色.出于个人喜好,他们想要表格中每个2 × 2的方形区域都包含奇数个(1 ...
- BZOJ 2303: [Apio2011]方格染色 [并查集 数学!]
题意: $n*m:n,m \le 10^6$的网格,每个$2 \times 2$的方格必须有1个或3个涂成红色,其余涂成蓝色 有一些方格已经有颜色 求方案数 太神了!!!花我三节课 首先想了一下只有两 ...
- BZOJ2303: [Apio2011]方格染色 【并查集】
Description Sam和他的妹妹Sara有一个包含n × m个方格的表格.她们想要将其的每个方格都染成红色或蓝色.出于个人喜好,他们想要表格中每个2 × 2的方形区域都包含奇数个(1 个或 3 ...
- [APIO2011]方格染色
题解: 挺不错的一道题目 首先4个里面只有1个1或者3个1 那么有一个特性就是4个数xor为1 为什么要用xor呢? 在于xor能把相同的数消去 然后用一般的套路 看看确定哪些值能确定全部 yy一下就 ...
- BZOJ2303 [Apio2011]方格染色 并查集
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2303 题意概括 现在有一个N*M矩阵,矩阵上只能填数字0或1 现在矩阵里已经有一些格子被填写了数字 ...
- BZOJ2303 APIO2011方格染色(并查集)
比较难想到的是将题目中的要求看做异或.那么有ai,j^ai+1,j^ai,j+1^ai+1,j+1=1.瞎化一化可以大胆猜想得到a1,1^a1,j^ai,1^ai,j=(i-1)*(j-1)& ...
随机推荐
- windows 无法启动 SQL Server (MSSQLSERVER) 服务(位于本地计算机上)。错误 1069由于登入失败而无法启动 。
windows 无法启动 SQL Server (MSSQLSERVER) 服务(位于本地计算机上).错误 1069由于登入失败而无法启动. 今天登录测试服务器突然出现无法登录的情况,经排查发现,SQ ...
- Dubbo 服务引入-Version2.7.5
1.服务引用原理 Dubbo 服务引用的时机有两个,第一个是在 Spring 容器调用 ReferenceBean 的 afterPropertiesSet 方法时引用服务,第二个是在 Referen ...
- Javaweb项目页面实时显示后台处理结果
http://www.cnblogs.com/dong-xu/p/6701271.html 此博文甚好,项目参照博主代码可实现. 前端页面: <%@ page language="ja ...
- vue-子组件为接受到父组件的数据
问题描述: 父组件请求数据,正在处理,未处理完,子组件已经加载,传递的为对象,子组件打印接受的数据为空 解决方式:(数据处理完之后,再强行给子组件赋值) 1.在子组件中添加 :ref="ch ...
- maven项目导出为jar包
1:ctrl + R 输入cmd 2:切换路径到自己的项目路径下 3:执行--> mvn assembly:assembly ( 若显示编码问题: 查看编码方式:chcp 修改编码:chcp ...
- ABBYY FineReader 15新增编辑页面布局功能
ABBYY FineReader 15(Windows系统) 新增编辑页面布局功能,允许用户修改PDF数字文档的页面布局,包括添加或者删除文字段落,文字块以及图片,更改段落,文字块,图片位置.添加或者 ...
- C# redis集群批量操作之slot计算出16384个字符串
引入一个大家都用的到的需求来说吧. 需求:要在三主三从的redis集群,存入数据,会对数据进行批量删除操作,数据要求要在redis集群负载均衡. 思路: 1.存入数据好办 1 var connect ...
- 【PYTEST】第四章Fixture
知识点: 利用fixture共享数据 conftest.py共享fixture 使用多个fixture fixture作用范围 usefixture 重命名 1. 利用fixture共享数据 test ...
- 一看就懂的:MySQL数据页以及页分裂机制
文章公号 首发!连载中~ 欢迎各位大佬关注, 回复:"抽奖" 还可参加抽活动 文末有二维码 一.知识回顾 回顾一下之前和大家分享的知识点 看了前面的文章,想必你肯定了解了什么是Bu ...
- yii2.0验证码的两种实现方式
第一种方式:采用model 1. 模型:Code.php <?phpnamespace app\models; use yii\base\Model;class Code extends Mod ...