Fake Maxpooling

题意:一个矩阵,A[I][J]=lcm(i,j),求所有k*k矩阵的最大值的和

求lcm矩阵有两种方法:
一种是官方题解的方法(打表?蒟蒻不太清楚叫什么):
运行时间:
在这里插入图片描述

for (int i = 1; i <= n; i++) {
	for (int j = 1; j <= m; j++) {
	   if (!gcd_rix[i][j]) {
		for (int k = 1; k * i <= n && k * j <= m; k++) {
			gcd_rix[k * i][k * j] = k;
			max_gcd[k * i][k * j] = k * i * j;
			}
		}
	}
 }

还有一种自然就是暴力了(勉强能过):
运行时间
在这里插入图片描述

int gcd(int a,int b) {
 while (b) {
  int c = a % b;
  a = b;
  b = c;
  gcd(a,b);
 }
 return a;
}

for (int i = 1; i <= n; i++) {
	for (int j = 1; j <= m; j++) {
		max_gcd[i][j] = i * j / gcd(i, j);
	}
}

上面都不是重点,重点是下面求解最大值和。我们先求解每一行从第j列到j-k+1列的最大值,然后在求解从第i行到底i+k-1行的最大值,进行上述两次操作后,得到的是第i行第j列到底i+k-1行j+k-1列的最大值。维护行/列最大值可以用单调队列维护。

AC代码(暴力版)

#include<cstdio>
#include <iostream>
#include <cstring>
#include <deque>
#include<cmath>
using namespace std;

const int N = 5005;

int gcd_rix[N][N];
int max_gcd[N][N];


int gcd(int a,int b) {
	while (b) {
		int c = a % b;
		a = b;
		b = c;
		gcd(a,b);
	}
	return a;
}

int main() {
	int n, m, v;
	scanf("%d %d %d", &n, &m, &v);
	int t = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			max_gcd[i][j] = i * j / gcd(i, j);
		}
	}
	for (int i = 1; i <= n; i++) {
		deque<int> dq;
		for (int j = 1; j <= m; j++) {
			while (!dq.empty() && max_gcd[i][dq.back()] < max_gcd[i][j]) dq.pop_back();
			while (!dq.empty() && j - dq.front() >= v) dq.pop_front();
			dq.push_back(j);
			max_gcd[i][j] = max_gcd[i][dq.front()];
		}
	}
	long long ans = 0;
	for (int i = 1; i <= m; i++) {
		deque<int> dq;
		for (int j = 1; j <= n; j++) {
			while (!dq.empty() && max_gcd[dq.back()][i] < max_gcd[j][i]) dq.pop_back();
			while (!dq.empty() && j - dq.front() >= v) dq.pop_front();
			dq.push_back(j);
			max_gcd[j][i] = max_gcd[dq.front()][i];
			if (j >= v && i >= v) ans = (ans+ max_gcd[j][i]);
		}
	}
	printf("%lld\n", ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值