专栏文章

题解:P13776 「o.OI R2」Easy ver.

P13776题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@mio7mnvd
此快照首次捕获于
2025/12/02 14:41
3 个月前
此快照最后确认于
2025/12/02 14:41
3 个月前
查看原文

题外话

好久没被一道黄题诈骗了。

思路

首先进行分类讨论。我们发现若 n×m<kn\times m<k 时可以随便填,因为根本没有 kk 连通块。由于每个位置可以填 1100,答案为 2n×m2^{n\times m}
我们继续讨论,发现当 n=1n=1m=1m=1n×m=kn\times m=k 时,答案为 2k12^{k-1}。因为若 n=1n=1m=1m=1,矩阵相当于一个序列,我们可以依次选长度为 kk 的区间,由于异或值都为 00,此时第 ii 个位置和第 i+ki+k 个位置的值必须相等。我们只需要保证前 kk 个位置有偶数个 11 即可。这是个经典的组合数问题,答案为 2k12^{k-1}n×m=kn\times m=k 同理。
我们注意力惊人,发现当 n×m>kn\times m>k 时矩阵的数必须全相等,举个例子:
对于图中 1,2,31,2,3 种选法,由于每回只有两个位置选与不选发生了改变,其它位置状态不变,而每回选完后 11 的个数都是偶数,所以可以推出最后一列后三个数相等。同理可得,整个矩阵的数都相等。
此时,若 kk 为偶数,那么矩阵可以全填 1100,答案为 22。若为奇数,那么只能全填 00 了,答案为 11

代码

CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
int t,n,m,k;
int qpow(int a,int b) {
	int ret=1;
	while(b) {
		if(b&1)ret*=a,ret%=mod;
		a*=a,a%=mod,b>>=1;
	}
	return ret;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>t;
	while(t--) {
		cin>>n>>m>>k;
		if(n*m<k) {
			cout<<qpow(2,n*m)<<"\n";
		} else if(n==1||m==1||n*m==k) {
            cout<<qpow(2,k-1)<<"\n";
		} else {
			if(k%2==0)cout<<2<<"\n";
			else cout<<1<<"\n";
		}
	}
	return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...