C 枚举左上角,F 枚举中间那条线的左端点然后统计
式子应该很好理解吧,乘法原理
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10,mod=998244353;
int n,m,up[N][N],rg[N][N],dw[N][N],T,ID,reC,reF,C,F;
bool a[N][N];
void solve(){
for(int i=3;i<=n;i++)
for(int j=1;j<=m-1;j++){
if(i-2<up[i][j]||a[i][j])continue;
int now=(rg[i-2][j]-rg[up[i][j]][j]-(j+1)*(i-2-up[i][j]))%mod*(rg[i][j]-rg[i-1][j]-j-1)%mod;
reC+=now;
reF+=now*(dw[i][j]-i-1)%mod;
}
return;
}
signed main(){
//freopen("plant.in","r",stdin);
//freopen("plant.out","w",stdout);
scanf("%d%d",&T,&ID);
while(T--){
scanf("%d%d%d%d",&n,&m,&C,&F);
for(int i=1;i<=n;i++){
string str;
cin>>str;
for(int j=1;j<=m;j++)
if(str[j-1]=='0')a[i][j]=0;
else a[i][j]=1;
}
for(int i=1,tp=0;i<=m;i++,tp=0)
for(int j=1;j<=n;j++)tp=a[j][i]?j:tp,up[j][i]=tp;
for(int i=1,tp=n+1;i<=m;i++,tp=n+1)
for(int j=n;j>=1;j--)tp=a[j][i]?j:tp,dw[j][i]=tp;
for(int i=1,tp=m+1;i<=n;i++,tp=m+1)
for(int j=m;j>=1;j--)tp=a[i][j]?j:tp,rg[i][j]=rg[i-1][j]+tp;
reC=reF=0;solve();
printf("%d %d\n",C*reC,F*reF);
}
// system("pause");
return 0;
}