静态RMQ模板题 contest 静态RMQ T2

Description

Wind设计了很多机器人。但是它们都认为自己是最强的,于是,一场比赛开始了。机器人们都想知道谁是最敏捷的,于是它们进行了如下一个比赛。首先,他们面前会有一排共n个数,它们比赛看谁能最先把每连续k个数中最大和最小值写下来,当然,这些机器人运算速度都很快,它们比赛的是谁写得快。但是Wind也想知道答案,你能帮助他吗?


Input

每组测试数据,第1行为n,k,第2行共n个数,为数字序列,所有数字均在longint范围内。


Output

共n-k+1行 第i行为第i—i+k-1这k个数中的最大和最小值


Hint

1<=k<=n<=100000


Solution

静态RMQ模板题,数据比较水,规范一点的话还是要用long long,不过用int在oj上也能过,下面的代码是没用long long的。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define maxn 100005
using namespace std;
int f_min[maxn][25],f_max[maxn][25],LoG[maxn],a[maxn];
int n,m,x,ans_min,ans_max,k;
void setlog_(){
	LoG[1]=0;
	for(int i=2;i<=maxn-1;i++){
		LoG[i]=LoG[(i>>1)]+1;
	}
}
void setf_max(){
	for(int i=1;i<=n;i++){
		f_max[i][0]=a[i];
	}
	for(int j=1;j<=LoG[n];j++){
		for(int i=1;i+(1<<j)-1<=n;i++){
			f_max[i][j]=max(f_max[i][j-1],f_max[i+(1<<(j-1))][j-1]);
		}
	}
}
void setf_min(){
	for(int i=1;i<=n;i++){
		f_min[i][0]=a[i];
	}
	for(int j=1;j<=LoG[n];j++){
		for(int i=1;i+(1<<j)-1<=n;i++){
			f_min[i][j]=min(f_min[i][j-1],f_min[i+(1<<(j-1))][j-1]);
		}
	}
}
int main(){
	setlog_();
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	setf_max();
	setf_min();
	for(int i=1;i+k-1<=n;i++){
		ans_max=max(f_max[i][LoG[k]],f_max[(i+k-1)-(1<<LoG[k])+1][LoG[k]]);
		ans_min=min(f_min[i][LoG[k]],f_min[(i+k-1)-(1<<LoG[k])+1][LoG[k]]);
		printf("%d %d\n",ans_max,ans_min);
	}
	return 0;
}
posted @ 2018-11-30 16:52  虚拟北方virtual_north。  阅读(112)  评论(0编辑  收藏  举报