loj 10120 最敏捷的机器人

题目描述

Wind 设计了很多机器人。但是它们都认为自己是最强的,于是,一场比赛开始了……

机器人们都想知道谁是最敏捷的,于是它们进行了如下一个比赛。首先,他们面前会有一排共 n 个数,它们比赛看谁能最先把每连续 k 个数中最大和最小值写下来,当然,这些机器人运算速度都很快,它们比赛的是谁写得快。

但是 Wind 也想知道答案,你能帮助他吗?

输入格式

第一行为 n,k,意义如题目描述。

第二行共 n 个数,为数字序列,所有数字均在 Pascallongint 范围内,即所有数均为整数,且在 [−2^31,2^31−1] 范围内。

输出格式

共 n−k+1 行,第 i 行为第 i 至第 i+k−1这 k个数中的最大和最小值。

样例

样例输入

5 3
1 2 3 4 5

样例输出

3 1
4 2
5 3

数据范围与提示

对于全部数据,1≤k≤n≤10^5

在普通rmq的基础上再加一个存最小值的数组就行了

(其实跟模板题没什么区别,但是为了水博客,我还是决定再发一遍)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 1e6 + 3;
int logg[N],f[N][20],s[N][20],a[N];
int n,k;
int main()
{
	scanf("%d%d",&n,&k);
	for(int i = 1;i <= n;i++)
	{
		scanf("%d",&a[i]);
	}
	logg[0] = -1;
	for(int i = 1;i <= n;i++)
	{
		f[i][0] = a[i];
		s[i][0] = a[i]; 
		logg[i] = logg[i >> 1] + 1;
	}
	for(int i = 1;i <= 21;i++)
	{
		for(int j = 1;j + (1 << i) - 1 <= n;j++) 
		{
			f[j][i] = max(f[j][i - 1],f[j + (1 << i - 1)][i - 1]);	
			s[j][i] = min(s[j][i - 1],s[j + (1 << i - 1)][i - 1]);
		} 
	}
	int q = logg[k];
	for(int i = 1;i <= n - k + 1;i++)
	{
		printf("%d %d\n",max(f[i][q],f[i + k - 1 - (1 << q) + 1][q]),min(s[i][q],s[i + k - 1 - (1 << q) + 1][q]));		
	}
	return 0;	
} 

猜你喜欢

转载自blog.csdn.net/qq_42914224/article/details/82890520