1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include <bits/stdc++.h> using namespace std; typedef long long LL; const int MAX_N = 3000 + 5; int n, m, a, b; LL g[MAX_N * MAX_N], x, y, z; LL t[MAX_N][MAX_N]; LL getG(int u) { if (g[u] != -1) return g[u]; else return g[u] = (getG(u - 1) * x % z + y % z) % z; } struct Node { LL v, id; friend bool operator == (const Node &nx, const Node &ny) { return nx.id == ny.id && nx.v == ny.v; } };
struct GreaterQueue { deque <Node> ori, q; void push(LL x, int pos) { ori.push_back({x, pos}); while (!q.empty() && q.back().v >= x) q.pop_back(); q.push_back({x, pos}); } void pop() { Node f = ori.front(); ori.pop_front(); if (f == q.front()) q.pop_front(); } int front() { return q.front().v; } void init() { while (!q.empty()) q.pop_back(); while (!ori.empty()) ori.pop_back(); } } qMin; LL sum = 0; int rMin[MAX_N][MAX_N], cMin[MAX_N][MAX_N]; int main() { memset(g, -1, sizeof g); scanf("%d%d%d%d", &n, &m, &a, &b); scanf("%lld%lld%lld%lld", &g[0], &x, &y, &z); g[0] %= z; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { t[i][j] = getG((i - 1) * m + j - 1); } } for (int i = 1; i <= n; ++i) { qMin.init(); for (int j = 1; j <= m; ++j) { if (j > b) qMin.pop(); qMin.push(t[i][j], j); rMin[i][j] = qMin.front(); } } for (int j = 1; j <= m; ++j) { qMin.init(); for (int i = 1; i <= n; ++i) { if (i > a) qMin.pop(); qMin.push(rMin[i][j], i); cMin[i][j] = qMin.front(); } } for (int i = a; i <= n; ++i) { for (int j = b; j <= m; ++j) { sum += cMin[i][j]; } } printf("%lld\n", sum); return 0; }
|