1. 程式人生 > 實用技巧 >2020牛客多校第二場(F)Fake Maxpooling

2020牛客多校第二場(F)Fake Maxpooling


給一個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;
}