比赛的时候感觉直接打表出矩阵会超时,就没想着打表。。。
要大胆的尝试。。。
先打表出矩阵(标程给出了n*M的时间复杂度,利用了筛选素数的思想),再用二维单调队列计算即可。
long long开数组,内存不够。。
#include<bits/stdc++.h>
using namespace std;
const int maxn=5001;
int a[5001][5001],n,m,h,mmax[maxn][maxn],que[maxn];
signed main()
{
scanf("%d %d %d",&n,&m,&h);
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++)//先行,该行,连续h列的最大值
{
int head=0,tail=0;//单调队列
for(int j=1;j<=m;j++)
{
while(head<tail&&a[i][j]>a[i][que[tail-1]]) tail--;//
que[tail++]=j;
while(head<tail&&que[tail-1]-que[head]+1>h) head++;
if(j>=h) mmax[i][j]=a[i][que[head]];
}
}
long long sum=0;
for(int j=h;j<=m;j++)//该列,连续h行的最大值;
{
int head=0,tail=0;
for(int i=1;i<=n;i++)
{
while(head<tail&&mmax[i][j]>mmax[que[tail-1]][j]) tail--;
que[tail++]=i;
while(head<tail&&que[tail-1]-que[head]+1>h) head++;
if(i<h) continue;
sum+=mmax[que[head]][j];
}
}
printf("%lld",sum);
}
京公网安备 11010502036488号