POJ 2823 Sliding Window 线段树水题

来源:http://poj.org/problem?id=2823

题意:给一些数,每次可以看k个数。从左向右顺序每次k个数,问每次的最大值 和最小值 是多少。

思路:RMQ的问题,用线段树松松水过。

代码:

#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;

const int N = 1000010;
struct tree{
	int lp,rp,minvalue,maxvalue;
	int getmid(){
	   return (lp + rp) / 2;
	}
}tt[N * 4];
struct ans{
	int minans,maxans;
}aa[N];
int num[N];
int min(int a,int b){
	return a < b ? a : b;
}
int max(int a,int b){
	return a > b ? a : b;
}
void built_tree(int lp,int rp,int pos){
	tt[pos].lp = lp;
	tt[pos].rp = rp;
	int mid = tt[pos].getmid();
	if(lp == rp){
		tt[pos].minvalue = tt[pos].maxvalue = num[lp];
		return;
	}
	built_tree(lp,mid,pos*2);
	built_tree(mid+1,rp,pos*2+1);
	tt[pos].minvalue = min(tt[pos*2].minvalue,tt[pos*2+1].minvalue);
	tt[pos].maxvalue = max(tt[pos*2].maxvalue,tt[pos*2+1].maxvalue);
}
int query(int lp,int rp,int pos ,int id){
	if(tt[pos].lp == lp && tt[pos].rp == rp){
	    if(id == 0)
			return tt[pos].minvalue;
		else
			return tt[pos].maxvalue;
	}
	int mid = tt[pos].getmid();
	if(mid >= rp)
		return query(lp,rp,pos*2,id);
	else if(mid < lp)
		return query(lp,rp,pos*2+1,id);
	else{
	   if(id == 0)
		   return min(query(lp,mid,pos*2,id),query(mid+1,rp,pos*2+1,id));
	   else
		   return max(query(lp,mid,pos*2,id),query(mid+1,rp,pos*2+1,id));
	}
}
int main(){
	//freopen("1.txt","r",stdin);
	int n,m;
	while(scanf("%d%d",&n,&m) != EOF){
	   for(int i = 1; i <= n; ++i)
		   scanf("%d",&num[i]);
	   built_tree(1,n,1);
	   for(int i = 1; i <= n - m + 1; ++i){
	      int j = i + m - 1;
		  aa[i].minans = query(i,j,1,0);
		  aa[i].maxans = query(i,j,1,1);
	   }
	   for(int i = 1; i < n - m + 1; ++i)
		   printf("%d ",aa[i].minans);
	   printf("%d\n",aa[n-m+1].minans);
	   for(int i = 1; i < n - m + 1; ++i)
		   printf("%d ",aa[i].maxans);
	   printf("%d\n",aa[n-m+1].maxans);
	}
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值