首页 > 其他分享 >sol.[APIO2011] 方格染色

sol.[APIO2011] 方格染色

时间:2023-08-18 14:26:06浏览次数:38  
标签:int APIO2011 sol times fa 异或 方格 oplus

题目描述

给定 \(k\) 个坐标的颜色 \((0\) 或 \(1)\),用 \(0\) 和 \(1\) 两种颜色对剩下的方格染色,使得对于任意 \(2 \times 2\) 的方格中,只有 \(1\) 个 \(1\) 或 \(3\) 个 \(1\)。求满足条件的染色方案数,答案对 \(10^9\) 取模。

数据范围:\(2 \leqslant n,m \leqslant 10^5\),\(0 \leqslant k \leqslant 10^5\)。

题解

本题解中 \(n, m\) 被视为同阶。

我们规定 \(f(x, y)\) 表示 \((x, y)\) 上的颜色。注意到,任意 $ 2 \times 2 $ 的方格中有 \(1\) 个或 \(3\) 个 \(1\),这等价于这四个方格的异或和为 \(1\),即对于任意 \(1 \le x < n\),\(1 \le y < m\),都满足:

\[f(x, y) \oplus f(x + 1, y) \oplus f(x, y + 1) \oplus f(x + 1, y + 1) = 1 \]


Theorem 1

所以如果合法方格内的第一行和第一列的格子颜色被确定,那么整个 $ n \times m $ 方格即可被唯一确定。

Prove 1

如果我们已知 $ 2 \times 2 $ 的格子中的 \(3\) 个的颜色,显然可以确定剩下一个的颜色。接下来按照第二行,第三行,\(\dots\),第 \(n\) 行的顺序,每行从左往右依次确定颜色,每次用 \((x - 1, y), (x, y - 1), (x - 1, y - 1)\) 三个点的颜色确定 \((x, y)\) 的颜色,即整个 $ n \times m $ 方格即可被唯一确定。

形式化地讲,利用数学归纳法,当 \(n = 1\) 或 \(m = 1\) 时结论显然成立。假定 \((n, m) = (x - 1, y)\) 和 \((n, m) = (x, y - 1)\) 结论成立,其中 \(x \ne 1, y \ne 1\),那么当 \((n, m) = (x, y)\) 时,\(f(x, y) = f(x - 1, y) \oplus f(x, y - 1) \oplus f(x - 1, y - 1) \oplus 1\),因此结论成立。


Theorem 2

合法方格中,对于任意 \(1 \le x \le n\),\(1 \le y \le m\),都有 \((1, 1)\),\((x, y)\),\((x, 1)\),\((1, y)\) 的颜色异或和为 \((x - 1)(y - 1) \bmod 2\),即

\[f(1, 1) \oplus f(1, y) \oplus f(x, 1) \oplus f(x, y) = \begin{cases} 1 & x \bmod 2 = y \bmod 2 = 0 \ \\ 0 & \text{Otherwise} \end{cases} \]

Prove 2

我们将这 $ x \times y $ 方格中的每个 $ 2 \times 2 $ 的单位方格全部异或起来,注意到,不在该方格边缘的格子被异或了 \(4\) 次,而在方格边缘又不在四个角的格子被异或了 \(2\) 次,它们的颜色对答案不做贡献,因此最后的异或和等于方格中四个角的异或和。由于每个 $ 2 \times 2 $ 的单位方格的异或值都为 \(1\),又共有 \((x - 1)(y - 1)\) 个单位方格,所以最后的异或和为 \((x - 1)(y - 1) \bmod 2\)。


由 \(\text{Theorem 1}\) 可知答案等价于第一行和第一列的合法染色数。

因此,我们考虑枚举 \((1, 1)\) 位置的颜色,对于每个已知的点 \((x, y)\),由 \(\text{Theorem 2}\) 可知 \((x, 1)\) 和 \((1, y)\) 的关系,用拓展域并查集维护。如果在维护中矛盾,此时不存在合法方案,否则我们记 \(cnt\) 为第一行和第一列中连通块的数量,由于和 \((1, 1)\) 相连的点颜色确定,因此这次枚举答案便为 \(2 ^ {cnt - 1}\),求和取模即可。

注意,若 \((1, 1)\) 的颜色已经确定,那么便不需要枚举。

时间复杂度为:$ \mathcal O(n \log n)$ 或 $ \mathcal O(n \times \alpha(n))$

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MOD = 1000000000;
struct dsu {
	vector<int> fa;
	dsu(int n) : fa(n + 2) { iota(fa.begin(), fa.end(), 0); };
	inline int Find(int r) {
		while (r != fa[r]) r = fa[r] = fa[fa[r]];
		return r;
	}
	inline bool Merge(int x, int y) {
		x = Find(x); y = Find(y);
		if (x == y) return true;
		else return fa[y] = x, false;
	}
}; // 并查集模板
inline int read() {
	int w = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		w = (w << 1) + (w << 3) + ch - 48;
		ch = getchar();
	}
	return w * f;
}
inline int Pow(int a, int b) {
	int ans = 1;
	a %= MOD;
	for (; b; b >>= 1) {
		if (b & 1) ans = ans * a % MOD;
		a = a * a % MOD;
	}
	return ans;
}
signed main() {
	int n, m, k, ans = 0, flag = -1;
	n = read(); m = read(); k = read();
	const int tot = n + m - 1; // 第一行和第一列的总点数
	vector<int> x(k + 1), y(k + 1), z(k + 1);
	for (int i = 1; i <= k; i++) {
		x[i] = read(); y[i] = read(); z[i] = read();
		if (y[i] == 1 && x[i] == 1) flag = z[i];
	}
	auto Pos = [&](int x, int op1, int op2) {
	    if (x == 1) {
	        if (op2 == 1) return tot + 1; // (1, 1) 的扩展域为 tot + 1
	        else return x;
	    }
		if (op2 == 1) x += tot; // 表示为扩展域
		if (op1 == 1) x += n - 1; // 表示在第一行上
		return x;
	};
	for (int rt = 0; rt <= 1; rt++) {
		int sum = 0;
		dsu A(tot << 1);
		if (flag != -1 && flag != rt) continue; // 若 (1, 1) 确定就不进行枚举
		for (int i = 1; i <= k; i++) {
			if (x[i] == 1 && y[i] == 1) continue;
			int x1 = Pos(x[i], 0, 0), y1 = Pos(y[i], 1, 0), x2 = Pos(x[i], 0, 1), y2 = Pos(y[i], 1, 1);
			int opt = ((x[i] & 1) | (y[i] & 1)) ^ (z[i] ^ rt);
			if (!opt) A.Merge(x1, y2), A.Merge(x2, y1);
			else A.Merge(x1, y1), A.Merge(x2, y2);
			if (A.Find(x1) == A.Find(x2) || A.Find(y1) == A.Find(y2)) {
				printf("0\n"); // 发生冲突
				return 0;
			}
		}
		for (int i = 1; i <= tot; i++) 
			if (i == A.Find(i)) sum++; // 统计联通块数目
		ans = (ans + Pow(2, sum - 1)) % MOD;
	}
	printf("%lld\n", ans);
	return 0;
}

标签:int,APIO2011,sol,times,fa,异或,方格,oplus
From: https://www.cnblogs.com/WTR2007/p/17640343.html

相关文章

  • sol. ABC246Ex
    动态DP模板题[ABC246Ex]01?Queries题目大意:给定一个长度为\(N\)且只包含?,1,0的字符串\(a\)。\(Q\)次操作,每次操作会修改字符串中的一个字符,并求出此时整个字符串中本质不同的子序列个数。众所周知,动态DP依然是DP的一种。先考虑没有修改操作,那么本题变为一个普......
  • SOLIDWORKS如何快速生成汇总BOM,SolidKits软件助您一臂之力
    物料清单是一个制造企业的核心文件数据。各个部门的活动都要用到物料清单,生产部门要根据物料清单来生产产品,库房要根据物料清单进行发料,财会部门要根据物料清单来计算成本,维修服务部门要通过物料清单了解需要什么备件等。但是各个部门需要用到的物料清单又不尽相同,因此再出物料清......
  • ARC 157 F Sol
    嫌弃讲题人的我,准备好好写一篇题解。linktoproblem观察数据范围:\(1\leN\le50\)。如果是\(20\),想到\(2^{20}\);如果是\(40\),想到\(2^{40\div2}\);若果是\(50\)呢?\(2^{25}\)有点大,于是想到\(2^{50\div3}\)。但是如何去凑?Hint\(N\)\(S\)\(T\)\(res\)\(6......
  • IPQ5018|Unlocking Affordable WiFi 6: The Ultimate Solution
    IPQ5018|UnlockingAffordableWiFi6:TheUltimateSolutionIntheeraoflightning-fastconnectivitydemands,findingtheperfectsynergybetweenperformance,efficiency,andcost-effectivenessisparamount.IntroducingtheDR5018-aWiFi6solutionthat......
  • Linux安装Solr-8.9.0
    Solr的工作原理可以简单地概括为以下几个步骤:1.索引创建:首先,Solr需要创建一个索引,用于存储要搜索的数据。索引是基于ApacheLucene构建的,它将文档拆分为字段,并对字段进行分析和标记化,以便进行更有效的搜索和匹配。2.数据导入:Solr可以从多种数据源导入数据,包括数据库、文件、Web......
  • [POI2014] PAN-Solar Panels
    区间\(\left(l,r\right]\)中存在\(n\)的倍数的充要条件是\(\left\lfloor\frac{r}{n}\right\rfloor>\left\lfloor\frac{l}{n}\right\rfloor\)。证明:记有整数\(k\)满足\(k\timesn\in\left(l,r\right]\)。那么有\[\displaystylel<k\timesn......
  • 【Solid works报错(无法连接到服务器)】
    报错有时,安装好SolidWorks后,打开时会弹出如下的错误弹窗原因最主要的原因之一为:安装的杀毒软件将SolidWorks服务设为禁止启动,每次开机后都需要进行手动的启动,这里以火绒为例。点击进入火绒之后,点击启动项管理,找到服务项中的SolidWorksFlexnetServer和SolidWorksLicens......
  • Jenkins Console 页中文显示乱码的问题
    背景:JenkinsServer为Helm安装,使用的是Bitnami的chart,当前app版本为Jenkins2.401.2添加一台Agent,该Agent的语言默认为zh_CN.UTF-8Pipeline使用docker的形式运行每个任务。表现形式:在Jenkins管理页面添加并配置Agent,使用SSH方式连接Agent,在连接日志界面有......
  • 达芬奇 DaVinci Resolve Studio 17.4影视后期调色软件下载和安装教程
    DaVinciResolve是一款专业的调色软件,将专业8K编辑,色彩校正,视觉效果和音频后期制作等功能集于一体的影视后期处理软件。广泛应用在影视后期,栏目包装,宣传片、广告片等领域。软件介绍调色页面设有全新HDR面板,可让您创建自定义色调范围的色轮,以便单独对任何色调范围进行微调!新增的......
  • idea实用插件推荐(1)-Grep Console
    1.简介GrepConsole可以根据日志等级设置不同的颜色,效果如下:安装点击File->Settings在搜索框里输入GrepConsole,点击install即可安装使用安装成功后,在idea控制台右键点击ShowGrepConsoleStatisticsinConsole,即可设置对应日志级别的颜色公众号:1号程序员,关注回复B0......