比赛的时候感觉直接打表出矩阵会超时,就没想着打表。。。
要大胆的尝试。。。
先打表出矩阵(标程给出了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); }