题目大意:给一个n×m的矩阵,对于第i行第j列的等于i与j的最小公倍数,求该矩阵中每个k×k大小的子矩阵中最大值的和
时间给的很充裕且矩阵为静态,可通过两次单调队列求得k×k范围内的最大值
#include<iostream>
#include<cstdio>
using namespace std;
int Num[5005][5005];
int gcd(int a,int b)
{
if(!b)return a;
return gcd(b,a%b);
}
struct Node{
int val,time;
};
int amx1[5005][5005];
int main()
{
int n,m,k;
long long ans=0;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;++i)
{
Node q1[10005]={0};
int head=5001,tail=5001;
for(int j=1;j<=m;++j)
{
Num[i][j]=i*j/gcd(i,j);
while(head!=tail&&j-q1[head-1].time>=k)head--;
while(head!=tail&&q1[tail].val<Num[i][j])tail++;
tail--;
q1[tail].time=j;
q1[tail].val=Num[i][j];
amx1[i][j]=q1[head-1].val;
}
}
for(int j=1;j<=m;++j)
{
Node q1[10005]={0};
int head=5001,tail=5001;
for(int i=1;i<=n;++i)
{
while(head!=tail&&i-q1[head-1].time>=k)head--;
while(head!=tail&&q1[tail].val<amx1[i][j])tail++;
tail--;
q1[tail].time=i;
q1[tail].val=amx1[i][j];
if(i>=k&&j>=k)ans+=q1[head-1].val;;
}
}
printf("%lld",ans);
return 0;
}


京公网安备 11010502036488号