Codeforces Round #574 (Div. 2) E.OpenStreetMap
题目的意思就是给你一个矩阵你要求给定子矩阵的最小值的和
单调队列扫两边即可
#include <bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f using namespace std; const int N = 1e7+7; const double eps = 1e-8; ll G[3007][3007]; ll col[3007][3007]; ll q[3007]; int main(){ ios::sync_with_stdio(false); cin.tie(0); int n,m,a,b; cin>>n>>m>>a>>b; ll g,x,y,z; cin>>g>>x>>y>>z; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ G[i][j]=g; g=((g%z*x%z)%z+y%z)%z; } int lie; for(int i=1;i<=n;i++){ int l,r; l=1,r=0; int cnt=0; for(int j=1;j<=m;j++){ while(l<=r&&G[i][j]<=G[i][q[r]]) --r; q[++r]=j; if(j>=b) col[i][++cnt]=G[i][q[l]]; while(l<=r&&(j-q[l]+1)>=b) ++l; } lie=cnt; } ll sum=0; for(int i=1;i<=lie;i++){ int l,r; l=1,r=0; int cnt=0; for(int j=1;j<=n;j++){ while(l<=r&&col[j][i]<=col[q[r]][i]) --r; q[++r]=j; if(j>=a) sum+=(col[q[l]][i]); while(l<=r&&(j-q[l]+1)>=a) ++l; } } cout<<sum<<endl; return 0; }