代码如下
#include<cstdio>
#include <cstring>
#include<cmath>
//#pragma warning(disable : 4996)
using namespace std;
#define ll unsigned long long
const int MAX = 1005;
const int MOD = 998244353;
/* (m n)
(0 0) (0 1) (0 2)
(1 0) (1 1) (1 2)
(2 0) (2 1) (2 2)
*/
int begin[MAX][MAX] = { 0 };
int right[MAX][MAX] = { 0 };
int down[MAX][MAX] = { 0 };
int sumc[MAX][MAX] = { 0 };
int sumf[MAX][MAX] = { 0 };
int main() {
//freopen("in.txt", "r", stdin);
int m, n = 0;
int T, M, N, c, f, x;
ll ansc = 0, ansf = 0;
scanf("%d %d\n", &T, &x);
//printf("%d\n",T);
for (int t = 0; t < T; t++) {
//printf("%d\n",T);
memset(right, -1, sizeof right);
memset(down, -1, sizeof down);
memset(begin, -1, sizeof begin);
scanf("%d %d %d %d\n", &M, &N, &c, &f);
//printf("%d %d %d %d\n", M, N, c, f);
for (m = 0; m < M; m++) {
for (n = 0; n < N; n++) {
scanf("%1d", &begin[m][n]);
//printf("%d",begin[m][n]);
}
scanf("\n");
//printf("\n");
}
//---------------
for (m = M - 1; m >= 0; m--) {
for (n = N - 1; n >= 0; n--) {
if (begin[m][n] == 0) {
right[m][n] = right[m][n + 1] + 1;
down[m][n] = down[m + 1][n] + 1;
}
if (begin[m][n] == 1) {
right[m][n] = -1;
down[m][n] = -1;
}
}
}
memset(sumc, 0, sizeof sumc);
memset(sumf, 0, sizeof sumf);
for (m = 0; m < M; m++) {
for (n = 0; n < N; n++) {
sumc[m][n] = sumc[m - 1][n] + right[m][n];
sumf[m][n] = sumf[m - 1][n] + (right[m][n]) * (down[m][n]);
}
}
//预处理完成
for (m = 0; m <= M; m++) {
for (n = 0; n < N; n++) {
if (right[m][n] >= 1 and down[m][n] >= 2) {
ansc += right[m][n] * (sumc[m + down[m][n]][n] - sumc[m + 1][n]);
}
if (right[m][n] >= 1 and down[m][n] >= 3) {
ansf += right[m][n] * (sumf[m + down[m][n]][n] - sumf[m + 1][n]);
}
ansc %= MOD;
ansf %= MOD;
}
}
ansc = (ll)(ansc * c) % MOD;
ansf = (ll)(ansf * f) % MOD;
printf("%llu %llu\n", ansc, ansf);
}
}