二维单调队列:
先对每一行做一次单调队列。
获得每一行的最值后,对这些最值再进行一次单调队列
'''
单调队列:
快速求出来区间为k的最大值和最小值
时间复杂度
预处理:O(nm)
求解:O(nm)
'''
def get_max(a,b,tot,k):
#a[] 每一行, b[] 每一列 tot 区间总长度, k 区间长度
q=[]
for i in range(tot):
#队头画出窗口
if q and q[0] <= i-k:
q.pop(0)
while q and a[q[-1]] <= a[i]:
q.pop()
q.append(i)
b[i] = a[q[0]]
def get_min(a,b,tot,k):
q=[]
for i in range(tot):
if q and q[0]<=i-k:
q.pop(0)
while q and a[q[-1]]>= a[i]:
q.pop()
q.append(i)
b[i] = a[q[0]]
N = 1010
mod = 998244353
w=[[0 for _ in range(N)] for _ in range(N)]
rmax = [[0 for _ in range(N)] for _ in range(N)]
rmin = [[0 for _ in range(N)] for _ in range(N)]
n,m,A,B = map(int,input().split())
for i in range(n):
w[i][:m]=map(int,input().split())
for i in range(n):
#
get_max(w[i],rmax[i],m,B)
get_min(w[i],rmin[i],m,B)
'''
for i in range(n):
for j in range(m):
print(rmax[i][j],end=" ")
print()
for i in range(n):
for j in range(m):
print(rmin[i][j],end=" ")
print()
'''
# a[N] 记录这一行的最值
a=[0 for _ in range(N)]
b=[0 for _ in range(N)]
c=[0 for _ in range(N)]
res=0
for i in range(B-1,m+1):
for j in range(n):
a[j] = rmax[j][i]
get_max(a,b,n,A)
for j in range(A-1,n+1):
a[j] = rmin[j][i]
get_min(a,c,n,A)
for j in range(A-1,n+1):
res = (res+b[j] * c[j])%mod
print(res)