牛客多校2020第二场F Fake Maxpooling(互质数对筛矩阵)

关于矩阵初始值我们可以用互质数对进行筛选,复杂度大致为N*M.
初始完值后,用二维单调队列维护矩阵最大值即可。
代码如下

#include <bits/stdc++.h>
using namespace std;
#define MAXN 5050
#define ll long long
int n,m,k;
int a[MAXN][MAXN];
int mx[MAXN][MAXN];
#define fore(l,r) for(int i=(l);i<=r;i++)
int main()
{
    
    
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
    
    
            if(!a[i][j])
            {
    
    
                int G=i*j/__gcd(i,j);
                int X=i;
                int Y=j;
                int k=1;
                while(X<=n&&Y<=m)
                {
    
    
                    a[X][Y]=k*G;k++;
                    X+=i;
                    Y+=j;
                }
            }
        }
    deque<int>p;
    for(int i=1;i<=n;i++)
    {
    
    
        while(!p.empty())p.pop_back();
        for(int j=1;j<=m;j++)
        {
    
    
            while (!p.empty() && j - p.back() >= k)p.pop_back();
            while (!p.empty() && a[i][j] >= a[i][p.front()])p.pop_front();
            if(!p.empty()&&a[i][j]>a[i][p.back()])p.push_back(j);
            else p.push_front(j);
            mx[i][j]= p.back();
        }
    }
    ll ans=0;
    for(int j=k;j<=m;j++)
    {
    
    
        while(!p.empty())p.pop_front();
        for(int i=1;i<=n;i++)
        {
    
    
            int x=a[i][mx[i][j]];
            while(!p.empty()&&i-p.back()>=k)p.pop_back();
            while(!p.empty()&&x>=a[p.front()][mx[p.front()][j]])p.pop_front();
            if(!p.empty()&&x>a[p.back()][mx[p.back()][j]])p.push_back(i);
            else p.push_front(i);
            if(i>=k)ans+=a[p.back()][mx[p.back()][j]];
        }
    }
    cout<<ans<<endl;
}

猜你喜欢

转载自blog.csdn.net/weixin_43353639/article/details/107366224