Fake Maxpooling
在初始化数组的时候如果直接求可能会t,所以用这种筛法,把复杂度降为\(O(nm)\),最后用单调队列来维护区间最大值。
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(!a[i][j])
for(int k=1;k*i<=n&&k*j<=m;++k)
a[i*k][j*k]=i*j*k;
// Created by CAD on 2020/7/13.
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define ll long long
using namespace std;
const int maxn=5005;
int a[maxn][maxn];
void init(int n,int m){
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(!a[i][j])
for(int k=1;k*i<=n&&k*j<=m;++k)
a[i*k][j*k]=i*j*k;
}
int ma[maxn][maxn];
int main(){
int n,m,k;cin>>n>>m>>k;
init(n,m);
for(int j=1;j<=m;++j){
deque<pii> q;
for(int i=1;i<=n;++i){
while(!q.empty()&&(q.front().fi<a[i][j]||i-q.front().se+1>k)) q.pop_front();
while(!q.empty()&&q.back().fi<a[i][j]) q.pop_back();
q.push_back({a[i][j],i});
ma[i][j]=q.front().fi;
}
}
ll ans=0;
for(int i=k;i<=n;++i){
deque<pii> q;
for(int j=1;j<=m;++j){
while(!q.empty()&&(q.front().fi<ma[i][j]||j-q.front().se+1>k)) q.pop_front();
while(!q.empty()&&q.back().fi<ma[i][j]) q.pop_back();
q.push_back({ma[i][j],j});
if(j>=k)
ans+=q.front().fi;
}
}
cout<<ans<<endl;
}
CAD加油!欢迎跟我一起讨论学习算法,QQ:1401650042