题意:给出一个矩阵 和a b 维护该矩阵包含的所有 a行b列子矩阵中的最小值 之和
用单调队列维护
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<'='<<(x)<<endl) #define pb push_back #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) typedef pair<ll,ll>pii; ////////////////////////////////// const int N=3000+5; ll ans; ll mp[N][N],g[N*N],x,n,m,z,y,a,b,g0; ll hang[N][N]; deque<pii>q; void h(ll *s ,ll *ans) { while(!q.empty())q.pop_back(); rep(i,1,b) { while(!q.empty()&&q.back().first>s[i])q.pop_back(); q.push_back(make_pair(s[i],i)); } ans[1]=q.front().first; rep(i,2,m-b+1) { if(!q.empty()&&q.front().second<i)q.pop_front(); while(!q.empty()&&q.back().first>s[i+b-1])q.pop_back(); q.push_back(make_pair(s[i+b-1],i+b-1)); ans[i]=q.front().first; } } void v(int x) { while(!q.empty())q.pop_back(); rep(i,1,a) { while(!q.empty()&&q.back().first>hang[i][x])q.pop_back(); q.push_back(make_pair(hang[i][x],i)); } mp[1][x]=q.front().first; rep(i,2,n-a+1) { if(!q.empty()&&q.front().second<i)q.pop_front(); while(!q.empty()&&q.back().first>hang[i+a-1][x])q.pop_back(); q.push_back(make_pair(hang[i+a-1][x],i+a-1)); mp[i][x]=q.front().first; } } ll sol() { scanf("%lld%lld%lld%lld",&n,&m,&a,&b); scanf("%lld%lld%lld%lld",&g0,&x,&y,&z); g[0]=g0; rep(i,1,n*m)g[i]=(g[i-1]*x+y)%z; rep(i,1,n)rep(j,1,m)mp[i][j]=g[(i-1)*m+j-1]; rep(i,1,n)h(mp[i],hang[i]); rep(i,1,m)v(i); ll ans=0; rep(i,1,n-a+1)rep(j,1,m-b+1) ans+=mp[i][j]; return ans; } int main(){ printf("%lld",sol()); }