1. 程式人生 > >POJ 2823 Sliding Window【RMQ壓縮(長度確定)】

POJ 2823 Sliding Window【RMQ壓縮(長度確定)】

題意:給一個長度為N的陣列,輸出所有區間長度為K的陣列元素的最大值與最小值;

AC程式碼:

#include<cstdio>
#include<algorithm>

using namespace std;

const int MAXN=1e6+11;
int a[MAXN],dmax[MAXN],dmin[MAXN],ma[MAXN],mi[MAXN];

void RMQ_init(int N,int K) {
	for(int i=0;i<N;++i) dmax[i]=dmin[i]=a[i];
	for(int j=1;(1<<j)<=K;++j) { //按照長度遞推即可 
		for(int i=0;i+(1<<j)-1<N;++i) {
			dmin[i]=min(dmin[i],dmin[i+(1<<j-1)]);
			dmax[i]=max(dmax[i],dmax[i+(1<<j-1)]);
		}
	}
}

int RMQ(int L,int R,int cho) {
	int k=0;
	while((1<<(k+1))<=R-L+1) ++k;
	if(cho) return max(dmax[L],dmax[R-(1<<k)+1]);
	return min(dmin[L],dmin[R-(1<<k)+1]);
} 
int main() { 
	int N,K; 
	while(~scanf("%d%d",&N,&K)) {
		for(int i=0;i<N;++i) scanf("%d",&a[i]);
		RMQ_init(N,K); 
		int cnt=N-K+1; //舉個例子算的快 
		for(int i=0;i<cnt;++i) {
			mi[i]=RMQ(i,i+K-1,0);
			ma[i]=RMQ(i,i+K-1,1); 
		}
		cnt--;
		for(int i=0;i<cnt;++i) printf("%d ",mi[i]);
		printf("%d\n",mi[cnt]);
		for(int i=0;i<cnt;++i) printf("%d ",ma[i]);
		printf("%d\n",ma[cnt]);
	}
	return 0;
}