题目链接
题目描述
Given a matrix of size n×m and an integerk, where A i,j=lcm(i,j), the least common multiple of i and j. You should determine the sum of the maximums among all k×k submatrices.
输入描述
Only one line containing three integers n,m,k(1≤n,m≤5000,1≤k≤min{n,m}).
输出描述
Only one line containing one integer, denoting the answer.
样例输入
3 4 2
样例输出
38
说明
题解
给定大小为n×m的矩阵和整数k,其中A {i,j} =lcm(i,j),是i和j的最小公倍数。找到所有大小为k×k的子矩阵中的最大值之和。下面是官方题解:
单调队列
单调队列:队列里的元素都是单调的。普通队列只允许先进先出,单调队列在入队时先进行判断———入队后是否是单调的,如果是就直接入队,如果不是就先从尾部把使它不单调的元素弹出。可以使用deque(双向队列)来控制进出。(如果不懂,可以点此)
代码
#include<bits/stdc++.h>
using namespace std;
int a[5005][5005],b[5005][5005];
deque<int>q;
int main()
{
int n,m,k;
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]) for(int k=1;k*i<=n&&k*j<=m;k++) a[k*i][k*j]=i*j*k;
for(int i=1;i<=n;i++)
{
while(!q.empty()) q.pop_back();
q.push_back(0);
for(int j=1;j<k;j++)
{
while(q.size()&&a[i][q.front()]<=a[i][j]) q.pop_back();
q.push_back(j);
}
for(int j=k;j<=m;j++)
{
while(q.size()&&q.front()<=j-k) q.pop_front();
while(q.size()&&a[i][q.back()]<=a[i][j]) q.pop_back();
q.push_back(j);
b[i][j]=max(b[i][j],a[i][q.front()]);
}
}
long long ans=0;
for(int j=k;j<=m;j++)
{
while(!q.empty()) q.pop_back();
q.push_back(0);
for(int i=1;i<k;i++)
{
while(q.size()&&b[q.front()][j]<=b[i][j]) q.pop_back();
q.push_back(i);
}
for(int i=k;i<=n;i++)
{
while(q.size()&&q.front()<=i-k) q.pop_front();
while(q.size()&&b[q.back()][j]<=b[i][j]) q.pop_back();
q.push_back(i);
ans+=b[q.front()][j];
}
}
printf("%lld",ans);
}