首页 > 其他分享 >codeforces 955 div 2 D

codeforces 955 div 2 D

时间:2024-07-09 17:52:34浏览次数:23  
标签:int 955 codeforces tot long sb using div sa

题目链接 D. Beauty of the mountains

题目大意



解题思路

首先记录所有雪山和没有雪山两种山峰的高度差为 \(tot\) ,然后对于每个可能的子矩,我们可以每次给所有山峰都加一或者减一,因此只要计算出矩阵内两种山峰的个数差的绝对值我们就能得到每次操作该子矩阵对tot的贡献 \(z_{i}\) ,因此我们只需要判断这些子矩阵的贡献值通过加减能否等于 \(tot\) 即可。

故原命题转化为求下面这个式子是否存在整数解, 即 \(d_{i}\) 全为整数,其中 \(d_{i}\) 是每个子矩阵的操作次数,

\[z_{1} \cdot d_{1} + z_{2} \cdot d_{2} + \dots + z_{q} \cdot d_{q} = tot \]

对于子矩阵的贡献采用二维前缀和即可求出
对于上面式子整数解的存在性问题只需要验证

\[tot \bmod gcd(z_{1}, z_{2}, \dots, z_{q}) = 0 \]

代码

#include <bits/stdc++.h>

#define debug cout << "debug" << endl;
#define debug1(a) cout << #a << " = " << a << endl;
#define debug2(a, b) \
	cout << #a << " = " << a << "  " << #b << " = " << b << endl;
#define debug3(a, b, c)                                                         \
	cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " \
		 << c << endl;
#define debug4(a, b, c, d)                                                      \
	cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " \
		 << c << "  " << #d << " = " << d << endl;
#define debug5(a, b, c, d, e)                                                   \
	cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " \
		 << c << "  " << #d << " = " << d << "  " << #e << " = " << e << endl;
#define caseT \
	int T;    \
	cin >> T; \
	while (T--)

// #define M(x, y) make_pair(x, y)
// #define M(x, y, z) make_tuple(x, y, z)
// #define int long long
// #define int __int128
using namespace std;
// using str = string;
using ull = unsigned long long;
using ll = long long;
// using pii = pair<int, int>;
// using tiii = tuple<int, int, int>;
const int N = 5e2 + 10;

void solve() {
	int n, m, k;
	cin >> n >> m >> k;
	vector<vector<int>> g(n+1, vector<int>(m+1)), sa(n+1, vector<int>(m+1)), sb(n+1, vector<int>(m+1));
	
	vector<int> z;
	ll tot = 0;

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> g[i][j];
		}
	}
	//计算二维前缀和
	for (int i = 0; i < n; i++) {
		string s;
		cin >> s;
		for (int j = 0; j < (int)s.size(); j++) {
			sa[i + 1][j + 1] = sa[i + 1][j] + sa[i][j + 1] - sa[i][j];
			sb[i + 1][j + 1] = sb[i + 1][j] + sb[i][j + 1] - sb[i][j];
			if (s[j] == '0') {
				sa[i + 1][j + 1] += 1;
				tot += g[i + 1][j + 1];
			} else {
				sb[i + 1][j + 1] += 1;
				tot -= g[i + 1][j + 1];
			}
		}
	}
	tot = abs(tot);
	// 计算子矩阵的贡献存起来
	for (int i = k; i <= n; i++) {
		for (int j = k; j <= m; j++) {
			int numa = sa[i][j] - sa[i][j - k] - sa[i - k][j] + sa[i - k][j - k];
			int numb = sb[i][j] - sb[i][j - k] - sb[i - k][j] + sb[i - k][j - k];
			int num = abs(numa - numb);
			if (num) {
				z.emplace_back(num);
			}
		}
	}
	 // 求解所有z的最大公因数
	int gc = 0;
	for (int i = 0; i < (int)z.size(); i++) {
		gc = __gcd(gc, z[i]);
	}
	// 特判tot==0,和gc==0
	if (tot == 0) {
		cout << "YES" << "\n";
	} else if (gc != 0 && tot % gc == 0) {
		cout << "YES" << "\n";
	} else {
		cout << "NO" << "\n";
	}

	return;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	caseT 
	solve();

	return 0;
}

标签:int,955,codeforces,tot,long,sb,using,div,sa
From: https://www.cnblogs.com/xrenenena/p/18292468

相关文章

  • Codeforces Round956(div2) A~C
    A.ArrayDivisibility题意:对于所有k=1~n,能被j=1~n整除,要求以这些j作为下标a[j]的和也能够被k整除思路:题目有点绕,但是仔细读懂题目其实会发现,其实就是从1到n按顺序输出一遍...,别被样例忽悠了voidsolve(){ intn; cin>>n; for(inti=1;i<=n;i++){ cout......
  • Codeforces Round 953(Div.2) 题解(A-E)
    CodeforcesRound953(Div.2)题解(A-E)A题意Alice有n本书,第一本书有\(a_1\)页,序号为1,第二本书有\(a_2\)页,序号为2,……,第n本书有\(a_n\)页,序号为n。Alice将把所有书分成两堆,并阅读每一堆中序号最大的一本书。Alice喜欢读书,请你告诉她,她最多可以读多少页的书。Solution第......
  • CodeForces CF1980C Sofia and the Lost Operations 题解 但是最后TLE 仅供思路参考
    CodeForcesCF1980CSofiaandtheLostOperations题解嗨嗨,又来了啊,蒟蒻再来一篇题解SofiaandtheLostOperations题面翻译索菲亚有一个包含$n$个整数的数组$a[1],a[2],…,a[n]$。有一天她对这个数组感到厌倦,于是决定顺序地对其应用$m$个修改操作。每个修改操作由一......
  • Codeforces Round #956 (Div. 2) C. Have Your Cake and Eat It Too
    CodeforcesRound#956(Div.2)C.HaveYourCakeandEatItToo题目大意:有长度为nnn的数组a......
  • / 用上指针 ,定义函数实现:终端输入 add + sub - mul * div / 执行 两个数 的加减乘除
    #include<stdio.h>#include<string.h>intmy_add(intdata1,intdata2){  returndata1+data2;}intmy_sub(intdata1,intdata2){  returndata1-data2;}intmy_mul(intdata1,intdata2){  returndata1*data2;}intmy_di......
  • Codeforces Round #956 (Div. 2) and ByteRace 2024
    CF1983A.ArrayDivisibility很快发现输出\(\mathbf{1\simn}\)符合题意。B.CornerTwist结论题。关键的充要条件是\(a,b\)的每一行/列的和模\(\mathbf{3}\)后相等。证明的话,首先要想到\(\mathbf{2\times2}\)的操作是可以完成所有大小的子矩阵操作的,手模一下可以发......
  • Codeforces Round 956 (Div. 2)
    A.ArrayDivisibilityArrayDivisibility直接输出1到n#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn;cin>>n;for(inti=1;i<=n;i++){cout<<i<<(i==n?'\n':'......
  • CodeForces CF1986C Update Queries题解
    来吧,兄弟们,再来篇题解,其实也不是题解,是我自己的思路/心得/体会UpdateQueries题面翻译题目翻译一共$t$组数据,每组数据给定长度为$n$的字符串$s$,长度为$m$的$ind$数组和字符串$c$。你可以任意安排$ind$数组和字符串$c$的顺序,并按照此顺序对字符串$s$进行$m$......
  • **CodeForces CF1928B Equalize题解**
    ok兄弟们,今天本蒟蒻来做一篇小小的题解Equalize题面翻译有一个给定的长度为$n$的数列$a$,现在加上一个排列$b$,即$c_i=a_i+b_i$。现在求对于所有可能的$b$,$c$中出现最多的数的出现次数的最大值。translateby@UniGravity.题目描述Vasyahastwohobbies—addingpe......
  • codeforces1849 D. Array Painting
    题目链接https://codeforces.com/problemset/problem/1849/D题意输入\(n(1\leqn\leq2e5)\)和长为\(n\)的数组\(a(0\leqa[i]\leq2)\)。最初,数组的每个元素都是蓝色的。有两种类型的操作:支付一枚硬币,选择一个蓝色元素,将其涂成红色。选择一个不等于\(0\)的红......