2020牛客多校第二場(F)Fake Maxpooling
阿新 • • 發佈:2020-07-14
給一個n和m的矩陣,求所有k*k子矩陣的最大值之和。
單調佇列按行求一遍,再按列求一遍。
#include <bits/stdc++.h> using namespace std; #define in freopen("data.in","r",stdin); #define out freopen("a.out","w",stdout); typedef long long ll; const int MAXN=5000+10; int a[MAXN][MAXN]; int gcd(int a,int b){ return b==0?a:gcd(b,a%b); } deque<int>deq; int main(){ ios::sync_with_stdio(false); int n,m,k; cin>>n>>m>>k; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ a[i][j]=i*j/gcd(i,j); } } for(int i=1;i<=n;i++){ int j=1,maxx=-1; while(j<=k){ while(deq.size() && a[i][deq.front()]<=a[i][j])deq.pop_front(); while(deq.size() && a[i][deq.back()]<=a[i][j])deq.pop_back(); deq.push_back(j); j++; } a[i][j-k]=a[i][deq.front()]; while(j<=m){ while(deq.size() && deq.front()<=j-k)deq.pop_front(); while(deq.size() && a[i][deq.front()]<=a[i][j])deq.pop_front(); while(deq.size() && a[i][deq.back()]<=a[i][j])deq.pop_back(); deq.push_back(j); j++; a[i][j-k]=a[i][deq.front()]; } while(deq.size())deq.pop_back(); } for(int i=1;i<=m-k+1;i++){ int j=1,maxx=-1; while(j<=k){ while(deq.size() && a[deq.front()][i]<=a[j][i])deq.pop_front(); while(deq.size() && a[deq.back()][i]<=a[j][i])deq.pop_back(); deq.push_back(j); j++; } a[j-k][i]=a[deq.front()][i]; while(j<=n){ while(deq.size() && deq.front()<=j-k)deq.pop_front(); while(deq.size() && a[deq.front()][i]<=a[j][i])deq.pop_front(); while(deq.size() && a[deq.back()][i]<=a[j][i])deq.pop_back(); deq.push_back(j); j++; a[j-k][i]=a[deq.front()][i]; } while(deq.size())deq.pop_back(); } ll ans=0LL; for(int i=1;i<=n-k+1;i++){ for(int j=1;j<=m-k+1;j++){ ans+=a[i][j]; //cout<<a[i][j]<<" "; } //cout<<endl; } cout<<ans<<endl; return 0; }