题意:
解法:
用单调队列预处理出h(i,j)向上b个格子范围内的最小值mi(i,j).
对于mi(,)的每一行,单调队列计算出mi(i,j)向左a个格子范围内的最小值M,
那么M是以(i,j)为右下角的a*b大小的矩阵的最小值,因此ans+=M.
复杂度O(n*m).
code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=3e3+5;
int h[maxm][maxm];
int mi[maxm][maxm];
int g[maxm*maxm];
int n,m,a,b;
int x,y,z;
void solve(){
cin>>n>>m>>a>>b;
cin>>g[0]>>x>>y>>z;
for(int i=1;i<=n*m;i++){
g[i]=(g[i-1]*x+y)%z;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
h[i][j]=g[(i-1)*m+j-1];
}
}
for(int j=1;j<=m;j++){
deque<int>q;
for(int i=1;i<=n;i++){
while(q.size()&&q.front()<i-a+1)q.pop_front();
while(q.size()&&h[q.back()][j]>=h[i][j])q.pop_back();
q.push_back(i);
mi[i][j]=h[q.front()][j];
}
}
int ans=0;
for(int i=a;i<=n;i++){
deque<int>q;
for(int j=1;j<=m;j++){
while(q.size()&&q.front()<j-b+1)q.pop_front();
while(q.size()&&mi[i][q.back()]>=mi[i][j])q.pop_back();
q.push_back(j);
if(j>=b){
ans+=mi[i][q.front()];
}
}
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}