没懂为什么就AC on#1#2#3#4
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1015,MOD=998244353;
char x;
int sum[N][N];
int all[N][N][2];//第i行 第j列起最长连续的土坑 + end_idx
int T,id;
int n,m,c,f;
int ans_c,ans_f;
void Summary()
{
for(int i=1;i<=n;i++)//第一横的行
{
for(int j=1;j<=n;j=all[i][j][1]+1)//枚举所在列数
{
if(!all[i][j][0]) continue;
for(int k=i+1;k<n;k++)//枚举第二横k+1
{
if(sum[k][j]==0||sum[k+1][j]==0) break;
else
{
if(all[i][j][0]-sum[i][j]>0&&all[k+1][j][0]-sum[k+1][j]>0)
{
int val=((all[i][j][0]-sum[i][j])*(all[k+1][j][0]-sum[k+1][j]))%MOD;
ans_c=(ans_c+val)%MOD;
int cnf=0;
for(int l=k+2;l<=n;l++)//枚举F的竖
{
if(sum[l][j]) cnf++;
else break;
}
ans_f=(ans_f+val*cnf%MOD)%MOD;
}
}
}
}
}
}
signed main()
{
scanf("%lld%lld",&T,&id);
while(T--)
{
ans_c=0; ans_f=0;
memset(sum,0,sizeof sum);
memset(all,0,sizeof all);
scanf("%lld%lld%lld%lld",&n,&m,&c,&f);
if(c==0&&f==0) { puts("0 0"); continue; }
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>x;
if(x=='0') sum[i][j]=sum[i][j-1]+1;
}
for(int i=1;i<=n;i++)
{
int end=n;
for(int j=n;j>=1;j--)
{
if(sum[i][j])
{
if(end==n)
{
all[i][j][0]=sum[i][j];
all[i][j][1]=end;
}
else
{
if(all[i][end][0]) all[i][j][0]=all[i][end][0];
else all[i][j][0]=sum[i][j];
all[i][j][1]=end;
}
}
else { end=j-1;all[i][j][1]=j+1; }
}
}
Summary();
printf("%lld %lld",c*ans_c,f*ans_f);
puts("");
}
}