CF-1195E Posted on 2019-07-29 | Edited on 2019-08-05 | In cf | Views: 题意给一个 $nm(1 \leq n, m \leq 3000)$ 的矩阵,求每一个 $ab$ 的子矩阵中最小值之和 题解先求出每一行长度为 $b$ 的序列的最小值,再求每一列长度为 $a$ 的序列的最小值 代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103#include <bits/stdc++.h>using namespace std;#define forl(i, l, r) for (int i = l; i <= r; i++)#define forr(i, r, l) for (int i = r; i >= l; i--)#define for1(i, n) for (int i = 1; i <= n; i++)#define fro1(i, n) for (int i = 1; i <= n; i++)#define for0(i, n) for (int i = 0; i < n; i++)#define fro0(i, n) for (int i = 0; i < n; i++)#define meminf(a) memset(a, inf, sizeof(a))#define mem_1(a) memset(a, -1, sizeof(a))#define mem0(a) memset(a, 0, sizeof(a))#define memcp(a,b) memcpy(a,b,sizeof(b))#define oper(type) bool operator <(const type y)const#define mp make_pair#define pu_b push_back#define pu_f push_front#define po_b pop_back#define po_f pop_front#define fi first#define se second#define whiel while#define retrun returntypedef pair<long long, long long> pll;typedef vector<long long> vll;typedef pair<int, int> pii;typedef unsigned long long ull;typedef vector<int> vii;typedef long double db;typedef long long ll;typedef int itn;int in(int &a,int &b,int &c,int &d){return scanf("%d%d%d%d",&a,&b,&c,&d);}int in(int &a,int &b,int &c){return scanf("%d%d%d",&a,&b,&c);}int in(int &a,int &b){return scanf("%d%d",&a,&b);}int in(ll &a){return scanf("%lld",&a);}int in(int &a){return scanf("%d",&a);}int in(char *s){return scanf("%s",s);}int in(char &s){return scanf("%c",&s);}int in(db &a){return scanf("%Lf",&a);}void out(int a){printf("%d ",a);}void outln(int a){printf("%d\n",a);}void out(ll a){printf("%lld ",a);}void outln(ll a){printf("%lld\n",a);}const db pi = acos((db)-1);const ll inf =0x3f3f3f3f;const db eps = 1e-8;const int N = 3.1e3;const ll mod = 1e9+7;int sign(db a) { return a < -eps ? -1 : a > eps;}int db_cmp(db a, db b){ return sign(a-b); } int minn[N][N],h[N][N],q[N];// q[i]表示从 i 开始长度为 len 的序列中的最小值的下标ll ans;void fun(int x,int n,int a){ int l=1,r=0; for1(i,n){ whiel(i-q[l]+1>a&&l<=r)l++; while(h[x][q[r]]>h[x][i]&&l<=r)r--; q[++r]=i; // cout<<i<<' '<<l<<' '<<q[l]<<endl; minn[x][i]=h[x][q[l]]; }}void fun2(int x,int n,int a){ int l=1,r=0; for(int i=1;i<=n;i++){ whiel(i-q[l]+1>a&&l<=r)l++; while(minn[q[r]][x]>minn[i][x]&&l<=r)r--; q[++r]=i; if(i>=a) ans+=minn[q[l]][x]; // minn[x][i]=h[x][q[l]]; }}int main() {#ifdef PerpEternal // freopen("/Users/perpeternal/Documents/Sketch/data/in.dat", "r", stdin); // freopen("/Users/perpeternal/Documents/Sketch/data/out.dat", "w", stdout);#endif //ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n,m,a,b,g,x,y,z; in(n,m,a,b); in(g,x,y,z); for0(i,n*m){ h[i/m+1][i%m+1]=g; g=(1ll*g*x+y)%z; } // for1(i,n){ // for1(j,m){ // out(h[i][j]); // } // puts(""); // } for1(i,n){ fun(i,m,b); } // for1(i,m)out(minn[1][i]); // puts(""); for(int i=b;i<=m;i++){ fun2(i,n,a); } outln(ans); return 0;}