牛客多校2020年第二场F

题目大意:有一个矩阵A,其中Aij=LCM(i,j)。问在该矩阵中所有的k子矩阵的最大值的和。

解题思路:先暴力求出目标矩阵,然后利用单调栈维护最大值下标。最后将答案加上即可。

代码:

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
std::mt19937 rnd(233);
#define pp pair<int,int>
#define ull unsigned long long
#define ls root<<1
#define rs root<<1|1
//#define int long long
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int NINF = 0xc0c0c0c0;
const int maxn =1e5+7;
const int Maxn = 5e6+7;
const double eps=1e-6;
const int mod=998244353;
int q[5100],maze[5100][5100];
int res[5100][5100];
signed main(){
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            maze[i][j]=i*j/__gcd(i,j);
        }
    }
    for(int i=1;i<=n;i++){
        int l=1,r=1;
        q[1]=1;
        for(int j=1;j<=m;j++){
            while(l<=r && j-k>=q[l])l++;
            while(l<=r && maze[i][j]>=maze[i][q[r]])r--;
            q[++r]=j;
            res[i][j]=q[l];
        }
    }
    int ans=0;
    for(int i=1;i<=m;i++){
        int l=1,r=1;
        q[1]=1;
        for(int j=1;j<=n;j++){
            while(l<=r && j-k>=q[l])l++;
            while(l<=r && maze[j][res[j][i]]>=maze[q[r]][res[q[r]][i]])r--;
            q[++r]=j;
            if(i>=k && j>=k)ans+=maze[q[l]][res[q[l]][i]];
        }
    }
    cout<<ans<<endl;
}

小记:开始想使用ST表做,但是可能因为不太熟练,一直T和WA(PS:ST表是可以过的),最后一个巨巨用另一个方法过了。总的来说,这场啥也没干。最后听题解发现单调栈的使用,因为很少使用单调栈,所以补一下啦。

你可能感兴趣的:(单调栈)