[CF1195E] OpenStreetMap - 二维单调队列
Description
给定一个 (n imes m(n,m le 3000)) 的矩阵,求出所有大小为 (a imes b) 的子矩形中的最小值的和
Solution
二维单调队列
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct MQueue
{
deque<pair<int, int>> que;
void Push(int value, int life)
{
while (que.size() && que.back().first >= value)
que.pop_back();
que.push_back({value, life});
}
void Filter(int time)
{
while (que.size() && que.front().second < time)
que.pop_front();
}
int Get(int time)
{
Filter(time);
return que.front().first;
}
};
vector<int> Process(const vector<int> &src, int width)
{
MQueue que;
for (int i = 0; i < width; i++)
que.Push(src[i], i + width - 1);
vector<int> ans;
ans.push_back(que.Get(width - 1));
for (int i = width; i < src.size(); i++)
que.Push(src[i], i + width - 1), ans.push_back(que.Get(i));
return ans;
}
signed main()
{
int n, m, a, b, g0, x, y, z;
cin >> n >> m >> a >> b >> g0 >> x >> y >> z;
vector<vector<int>> A(n, vector<int>(m));
int g = g0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
A[i][j] = g;
g = (g * x + y) % z;
}
vector<vector<int>> B(n);
for (int i = 0; i < n; i++)
B[i] = Process(A[i], b);
vector<vector<int>> C(B[0].size(), vector<int>(B.size()));
for (int i = 0; i < C.size(); i++)
for (int j = 0; j < C[0].size(); j++)
C[i][j] = B[j][i];
int ans = 0;
for (int i = 0; i < C.size(); i++)
{
auto tmp = Process(C[i], a);
for (int j = 0; j < tmp.size(); j++)
{
ans += tmp[j];
}
}
cout << ans << endl;
}