题意:

$n*m:n,m \le 10^6$的网格,每个$2 \times 2$的方格必须有1个或3个涂成红色,其余涂成蓝色

有一些方格已经有颜色

求方案数


太神了!!!花我三节课

首先想了一下只有两行,发现可以直接$f[i][3]\ DP$出来,每一列放的方案只与上一列有关

如果有多行呢,我们可以把上一列放的状态状压$f[i][s]$,然后枚举转移

复杂度爆炸

好,看一眼题解

woc题解说的些什么东西根本看不懂,还是自己想吧

发现,貌似一个状态只有两个后继状态唉,就是说这一列的右面一列只有两种放法是合法的

数学归纳法证一下,两行的情况每种列的放法有两个后继,设n行成立,那么n+1行的下一列选或不选就已经确定了...好像成立唉!

并且这两个后继还是每个位置都相反的!

总算看明白题解那句:

如果确定了第一行,接下来的每一行只会是 1.上一行所有奇数列异或1后得到 2.上一行所有偶数列异或1后得到 (这里把之前的行列倒换了)

其实可以直观理解,因为要保证是奇性啊

这样的话,不考虑已经涂色的,方案数就是第一行的方案数*(行数-1)$2^{n+m-1}$了

考虑涂色!

首先,每个有涂色的行两个后继状态只有一个合法了

再考虑这一行的涂色对第一行的影响,如果有一行两个位置$x,y$已经涂色,因为只有那两种变换所以:

$1.\ x,y同奇偶,每行都必须同色$

$2.\ x,y异奇偶,跟这一行同奇偶的行必须同色,异奇偶的行必须异色$

用个种类并查集就可以判断无解了!

方案数?把有关系限制的列连起来,求连通块数就行了

注意第一行如果有已经涂色的,颜色就直接确定了而不是同色或者异色,所以包含他们的连通块不能再考虑

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
#define pii pair<int, int>
#define MP make_pair
#define fir first
#define sec second
const int N=1e6+5, P=1e9;
typedef long long ll;
inline int read(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}int n, m, k, c[N], p, x, y;
struct meow{int r, c;}t;
vector<meow> q[N];
int fa[N];
int find(int x) {return x==fa[x] ? x : fa[x]=find(fa[x]);}
struct UFS{int fa[N], val[N];int find(int x) {if(x == fa[x]) return x;int root = find(fa[x]);val[x] ^= val[fa[x]];return fa[x] = root;}bool Union(int x, int y, int p) {int f1 = find(x), f2 = find(y);if(f1 != f2) {fa[f1] = f2;val[f1] = val[x]^val[y]^p;} else if((val[x]^val[y]) != p) return false;return true;}
}F;
int fix[N], mark[N];
int Pow(ll a, int b) {ll ans=1;for(; b; b>>=1, a=a*a%P) if(b&1) ans=ans*a%P;return ans;
}
int main() {freopen("in","r",stdin);n=read(); m=read(); k=read();for(int i=1; i<=k; i++) {x=read(), t.r=read(), t.c=read(), q[x].push_back(t);mark[x] = 1;if(x == 1) fix[t.r] = 1;}for(int i=1; i<=m; i++) fa[i] = F.fa[i] = i;for(int i=1; i<=n; i++)for(int j=1; j<(int)q[i].size(); j++) {int a = q[i][j-1].c, b = q[i][j].c, x=q[i][j-1].r, y=q[i][j].r;int f1 = find(x), f2 = find(y);fa[f1] = f2;if(fix[f1]) fix[f2] = 1;int p = a^b; if((x&1) != (y&1)) p ^= (i-1)&1;if(!F.Union(x, y, p)) {puts("0"); return 0;}}int ans = 0;for(int i=2; i<=n; i++) ans += !mark[i];for(int i=1; i<=m; i++) if(fa[i]==i && !fix[i]) ans++;printf("%d\n", Pow(2, ans));
}

转载于:https://www.cnblogs.com/candy99/p/6595028.html

BZOJ 2303: [Apio2011]方格染色 [并查集 数学!]相关推荐

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

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

  2. python方格染色_Luogu P3631 [APIO2011]方格染色

    思路 对于这道题,我们从题目里可以知道,蓝色代表的方块为0,红色代表的方块为1.按照题目要求,如果换一种说法,那就是对于一个2*2的方格,其中1的个数必定有奇数个,这样的话,每个方格里的所 有数的异或 ...

  3. AT2675 [AGC018F] Two Trees (构造+二分图染色+并查集)

    description 戳我看题目 solution 正解说是欧拉回路,但是于私而言非常难懂,如果有兴趣可以看香香mm的博客 定义一个点如果有偶数个儿子,就为奇点:如果有奇数个儿子,就为偶点 对于一个 ...

  4. Bzoj P2054 疯狂的馒头 | 并查集

    题目链接 思路:因为每次染色都会将某些馒头的颜色彻底更改,所以每个馒头的最终的颜色其实是由最后一次染色决定的,那么我们只考虑最后一次染色即可.对此,我们可以从后往前倒着染色,当目前的染色区间中存在白色 ...

  5. BZOJ 1370: [Baltic2003]Gang团伙 [并查集 拆点 | 种类并查集WA]

    题意: 朋友的朋友是朋友,敌人的敌人是朋友:朋友形成团伙,求最多有多少团伙 种类并查集WA了一节课,原因是,只有那两种关系才成立,诸如朋友的敌人是朋友之类的都不成立! 所以拆点做吧 #include ...

  6. [BZOJ 4551][Tjoi2016Heoi2016]树(并查集)

    Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标 ...

  7. BZOJ 2959 长跑 (LCT、并查集)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2959 题解 真是被这题搞得心态大崩--调了7个小时--然而并查集都能写成\(O(n^2) ...

  8. bzoj 4551: [Tjoi2016Heoi2016]树【并查集】

    看起来像是并查集,但是是拆集合,考虑时间倒流,先把标记都打上,然后把并查集做出来 每次到一个修改点就把这个点的计数s[u]--,当这个s为0时就把这个点和他的父亲合并(因为可能有多次标记) #incl ...

  9. [APIO2011] 方格染色

    设a[i,j]=0/1表示格子的颜色,由题意,f(i,j)=a[i,j]^a[i+1,j]^a[i,j+1]^a[i+1,j+1]=1. 对于约束a[x,y]=c(x>1,y>1), ^^ ...

最新文章

  1. 如何获取客户端的真实IP
  2. WCF系列之.net(3.0/3.5)Rest使用示例
  3. Java中的内存泄露的几种可能
  4. 核心系统100%上云!全球最大流量洪峰,阿里云扛住了
  5. 随想录(cloud 网络库)
  6. echarts横轴展示不全使用滚动条(dataZoom)的方法
  7. 如何设计一个完美的权限管理模块
  8. VMware14虚拟机安装Mac OS教程
  9. win10的计算机策略组,Win10家庭版如何添加组策略功能?
  10. 电脑屏幕蓝光过滤护眼工具:f.lux for Mac
  11. 引起相变的无序结构域(IDRs)怎么预测?跟踪热点,提升文章档次!
  12. HDU 4889 Scary Path Finding Algorithm
  13. 隐私计算头条周刊(7.31-8.6)
  14. 微信小程序 - 二维码数据解析,如何扫码进入开发版测试二维码数据
  15. java计算机毕业设计计算机课程在线培训学习管理系统MyBatis+系统+LW文档+源码+调试部署
  16. 深入探索透视投影变换(续)
  17. Linux ping 测试IP地址与 telnet 测试IP端口
  18. linux支持的笔记本无线网卡,用笔记本网卡CDLINUX支持30211版,加载成功,联想E40笔记本无线网卡!!!...
  19. mysql里的die_mysql中die函数的问题
  20. Lightroom“夏日清凉”调色思路

热门文章

  1. 亿纬锂能拟募资90亿:刘金成骆锦红夫妇合计认购60亿 布局光谷
  2. 三星SCH-I739官方原版ROM下载及刷机教程
  3. linux 安全狗 加入云服务,centos6.5安装网站安全狗并加入服云管理
  4. 关于 MySQL Installer is running in Community mode 的解决办法
  5. 计算机网络技术专业的英文名称,计算机网络技术专业,computer network major,音标,读音,翻译,英文例句,英语词典...
  6. npm常用命令详细教学
  7. div不换行时如何解决
  8. Task6:文本函数查找函数
  9. STM32F10x并行驱动lcd12864遇到的问题及其解决方案
  10. Tecnomatix Plant Simulation AGV物流技巧