2020牛客多校 第二场 F-Fake Maxpooling (快速lcm + 二维单调队列)

题目链接: F-Fake Maxpooling

Description

给出 n, m, k 求矩阵 a[n][m] 中 k方阵大小的区域内的最大值的和,a[i][j] = lcm(i, j)。

Sample Input

3 4 2

Sample Output

38

More Info

  • 1 <= n, m <= 5000
  • 1 <= k <= {n, m}

Method

  • 可以暴力产生最小公倍数矩阵,可以花费时间换空间; 我就是补题的时候因为空间被卡的,蒟蒻哭泣
  • 也可以用空间换时间,建一个gcd矩阵,然后找到lcm矩阵a;
  • 得到a矩阵后进行两次单调队列即可,第一次将每一列的k区间的最值更新到a矩阵中,第二次则将每一行的k区间的最值更新,更新后的矩阵a[i][j]即为在1-i、1-j区间内 k方阵内的最大值;
  • 最后将i-n、j-m的a[i][j]的值求和即可;

Code

详见注释

#include <iostream>
#include <cstdio>
#include <deque>

using namespace std;
#define ll long long
#define Max 5005
template<typename T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
int a[Max][Max], Gcd[Max][Max];
ll sum=0;


void solve(int &n, int &m, int &k)
{
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
			if(!Gcd[i][j]) {
				//a[i][j] = i*j/gcd(i, j);
				for(int v=1; v*i<=n&&v*j<=m; v++)		//快速求最小公倍数表 
				{
					Gcd[v*i][v*j] = v;
					a[v*i][v*j] = i*j*v;
				}
			}
	for(int i=1; i<=n; i++)								//单调队列 求纵向最值 
	{
		deque<int> dq;									//STL-双端队列 
		for(int j=1; j<=m; j++)
		{
			while(!dq.empty()&&a[i][j] > a[i][dq.back()]) dq.pop_back();
			while(!dq.empty()&&j-dq.front() >= k) dq.pop_front();
			dq.push_back(j);
			a[i][j] = a[i][dq.front()];					//更新矩阵 
		}
	}
	for(int i=1; i<=m; i++)								//单调队列 求横向最值 
	{
		deque<int> dq;									//STL-双端队列 
		for(int j=1; j<=n; j++)
		{
			while(!dq.empty()&&a[j][i] > a[dq.back()][i]) dq.pop_back();
			while(!dq.empty()&&j-dq.front() >= k) dq.pop_front();
			dq.push_back(j);
			a[j][i] = a[dq.front()][i];					//更新矩阵 
			
			if (j >= k&& i >= k) sum += a[j][i];		//将所有k矩阵的最值求和 
		}
	}
}

int main()
{
	int n, m, k;
	scanf("%d%d%d", &n, &m, &k);
	solve(n, m, k);
	/*for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=m; j++)
			printf("%lld ", a[i][j]);
		printf("\n");
	}*/
	printf("%lld", sum);
	return 0;
}


蒟蒻一只,欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值