BZOJ2303 [Apio2011]方格染色 并查集
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ2303
题意概括
现在有一个N*M矩阵,矩阵上只能填数字0或1
现在矩阵里已经有一些格子被填写了数字,询问是否存在一种填写方案使得「任意一个2*2的矩阵异或和为1」,输出方案总数
题解
我们发现当我们已经确定(1,1)的颜色为1的时候:
我们知道c(i,j)。
那么如果i和j都是偶数,那么就有c(1,1)^c(i,1)^c(1,j)^c(i,j)==1
否则就是0。
因为假设s(i,j)表示以i,j为左上角的2*2矩阵异或起来,那么:
S(1,1)^S(1,2)^...^S(1,j)^S(2,1)^S(2,2)^...^S(i-1,j-1)=c(1,1)^c(i,1)^c(1,j)^c(i,j)。
而左式就等于(i-1)*(j-1)个1异或。
这是一个好东西。
然后我们枚举(1,1)的颜色,然后对于每一个C(i,j)就可以得到一组C(i,1)和C(1,j)的关系。
但是当i=1或者j=1的时候,是得到一个C(i,1)或者C(1,j)的答案。
最后得到关系之后,只需要看看是否矛盾。
然后统计连通块数,就是自由元的总数,每一个自由元有2种取值,于是答案显而易见。
注意输入有i=j=1的情况要特判。
细节有点多。
代码
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstdlib>
using namespace std;
const int N=1000005,mod=1e9;
int n,m,ad,k,v[N*4],fa[N*4];
struct color{
int a,b,c;
}co[N];
int Turn(int a,int b){
return a==1?(b-1):(a-1+m-1);
}
int getf(int k){
return fa[k]==k?k:fa[k]=getf(fa[k]);
}
int solve(){
memset(v,-1,sizeof v);
for (int i=1;i<=ad*2;i++)
fa[i]=i;
for (int i=1;i<=k;i++){
int a=co[i].a,b=co[i].b,c=co[i].c;
if (a==1&&b==1)
continue;
if (a==1||b==1){
v[Turn(a,b)]=c,v[Turn(a,b)+ad]=c^1;
continue;
}
int A=Turn(a,1),B=Turn(1,b);
int res=(!(a&1)&&!(b&1))^c;
if (res){
if (getf(A)==getf(B))
return 0;
fa[getf(A)]=getf(B+ad);
fa[getf(B)]=getf(A+ad);
}
else {
if (getf(A)==getf(B+ad))
return 0;
fa[getf(A)]=getf(B);
fa[getf(A+ad)]=getf(B+ad);
}
}
for (int i=1;i<=ad*2;i++){
if (v[i]==-1)
continue;
if (v[getf(i)]==-1)
v[getf(i)]=v[i];
else if (v[getf(i)]!=v[i])
return 0;
}
int res=1,ans=0;
for (int i=1;i<=ad*2;i++)
if (getf(i)==i&&v[i]==-1)
ans++;
for (ans>>=1;ans--;)
res=res*2%mod;
return res;
}
int main(){
scanf("%d%d%d",&n,&m,&k);
ad=n+m-2;
int flag=-1;
for (int i=1;i<=k;i++){
scanf("%d%d%d",&co[i].a,&co[i].b,&co[i].c);
if (co[i].a==1&&co[i].b==1)
flag=co[i].c;
}
int ans1=solve();
for (int i=1;i<=k;i++)
if (co[i].a>1&&co[i].b>1)
co[i].c^=1;
int ans2=solve();
int ans=0;
if (flag==-1)
ans=(ans1+ans2)%mod;
else
ans=flag?ans2:ans1;
printf("%d",ans);
return 0;
}
BZOJ2303 [Apio2011]方格染色 并查集的更多相关文章
- BZOJ 2303: [Apio2011]方格染色 [并查集 数学!]
题意: $n*m:n,m \le 10^6$的网格,每个$2 \times 2$的方格必须有1个或3个涂成红色,其余涂成蓝色 有一些方格已经有颜色 求方案数 太神了!!!花我三节课 首先想了一下只有两 ...
- [BZOJ2303][Apio2011]方格染色
[BZOJ2303][Apio2011]方格染色 试题描述 Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好,他们想要表格中每个2 × ...
- BZOJ2303: [Apio2011]方格染色 【并查集】
Description Sam和他的妹妹Sara有一个包含n × m个方格的表格.她们想要将其的每个方格都染成红色或蓝色.出于个人喜好,他们想要表格中每个2 × 2的方形区域都包含奇数个(1 个或 3 ...
- BZOJ2303 APIO2011方格染色
这题太神了 首先我们可以发现只有当i和j都是偶数时a[1][1]^a[1][j]^a[i][1]^a[i][j]=1才满足情况,其它时都为0 所以我们可以先把i和j都为偶数的地方^1变为0 下面才是最 ...
- 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)& ...
- BZOJ_2303_[Apio2011]方格染色 _并查集
BZOJ_2303_[Apio2011]方格染色 _并查集 Description Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好, ...
- bzoj 2303: [Apio2011]方格染色【并查集】
画图可知,每一行的状态转移到下一行只有两种:奇数列不变,偶数列^1:偶数列不变,奇数列^1 所以同一行相邻的变革染色格子要放到同一个并查集里,表示这个联通块里的列是联动的 最后统计下联通块数(不包括第 ...
- bzoj 2303: [Apio2011]方格染色
传送门 Description Sam和他的妹妹Sara有一个包含n × m个方格的表格.她们想要将其的每个方格都染成红色或蓝色.出于个人喜好,他们想要表格中每个2 × 2的方形区域都包含奇数个(1 ...
- 【题解】P3631 [APIO2011]方格染色
很有意思的一道题,所以单独拿出来了. 完整分享看 这里 题目链接 luogu 题意 有一个包含 \(n \times m\) 个方格的表格.要将其中的每个方格都染成红色或蓝色.表格中每个 \(2 \t ...
随机推荐
- 22. SpringBoot 集成 Mybatis
1. 引入Mybatis的maven 依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> < ...
- Redis 主从模式
系统:Centos6.6x64安装目录:/usr/local/主:192.168.100.103从:192.168.100.104 ,下载安装: 安装依赖: # yum install gcc tcl ...
- [C++]指针和指向数组的指针[一维数组与指针]
1.一维数组与指针 形如:int型 数组 a[10] 1)&a[0] 地址常量;地址类型:int *型 ; 存储数组a的首地址 ...
- python技巧 python2中的除法结果为0
在python2中执行除法操作如果结果小于1就会返回0 如下面的例子: >>>81/82 0 如果你需要返回"正确的结果 ",有两种方法: 在脚本中引入from ...
- HDU小小练
hdu1253胜利大逃亡(bfs) 题意:就是城堡问题,找出可通行路径即可 思路:三维BFS,设定前后上下左右6个方向搜索,注意开始的时候人站的位置可以是墙. hdu1495非常可乐(bfs) 题意: ...
- 第18月第25天 github下载单个文件夹 git命令
1. 用 SVN 即可. 举例说明: 譬如这个项目: Mooophy/Cpp-Primer · GitHub, 我只想看 ch03 文件夹的代码怎么办? 先打开 ch03, 其 URL 为: &quo ...
- 阿里云3台机器搭建Hadoop HA服务
1 Mac电脑配置 阿里云配置机器 选择配置 按量付费 选择三台机器 2核8G
- 重新看halcon模板匹配
工业中模板匹配有很多需求. 代码如下: read_image (Image, 'J:/测试图片/test1/1.bmp') get_image_size (Image, Width, Height) ...
- 编写灵活、稳定、高质量的 css代码的规范
语法 用两个空格来代替制表符(tab) -- 这是唯一能保证在所有环境下获得一致展现的方法. 为选择器分组时,将单独的选择器单独放在一行. 为了代码的易读性,在每个声明块的左花括号前添加一个空格. 声 ...
- 在Mysql中查询两个时间段的差,可以是秒,天,星期,月份,年...
SELECT TIMESTAMPDIFF(SECOND, now(), "2016-11-11 00:00:00") 语法为:TIMESTAMPDIFF(unit,datetime ...