poj 3264 Balanced Lineup(RMQ && 线段树)

题目链接:http://poj.org/problem?id=3264

题意:求出一个给定的区间的最大差值。

很典型的RMQ问题,也可以用线段树做。

(Ps:不明白为什么poj上c++提交第一份代码会CE,log函数不是在math头文件里么?G++可以交)

①RMQ(3750ms):

<pre name="code" class="cpp">#include<iostream>
#include<cstdio>
#include<cstring>
#include<math.h>
#include<algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=50005;
int n,q;
int f[maxn];
int minNum[maxn][32],maxNum[maxn][32];


//dp[i, j]表示从第i个数起连续2^j个数中的最大值;
void RMQ(){
	for(int i=1;i<=n;i++)
		minNum[i][0]=maxNum[i][0]=f[i];
	for(int j=1;j<=20;j++){
		for(int i=1;i<=n;i++){
			if(i+(1<<j)-1<=n){
				minNum[i][j]=min(minNum[i][j-1],minNum[i+(1<<(j-1))][j-1]);
				maxNum[i][j]=max(maxNum[i][j-1],maxNum[i+(1<<(j-1))][j-1]);
			}
		}
	}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
#endif
	while(~scanf("%d%d",&n,&q)){
		for(int i=1;i<=n;i++)
			scanf("%d",&f[i]);
		RMQ();
		int a,b;
		while(q--){
			scanf("%d%d",&a,&b);
			int k=(int)log2(b-a+1);
			int intervalMin=min(minNum[a][k],minNum[b-(1<<k)+1][k]);
			int intervalMax=max(maxNum[a][k],maxNum[b-(1<<k)+1][k]);
			printf("%d\n",intervalMax-intervalMin);
		}
	}
	return 0;
}


 
 

②线段树(1735ms):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=50005;
int n,q;
int minNum,maxNum;

struct segmentTree{
	int l;
	int r;
	int min;
	int max;
}node[3*maxn];

void PushUp(int rt){
	node[rt].min=min(node[rt<<1].min,node[rt<<1|1].min);
	node[rt].max=max(node[rt<<1].max,node[rt<<1|1].max);
}

void build(int rt,int l,int r){
	node[rt].l=l;
	node[rt].r=r;
	if(l==r) return ;
	int mid=(l+r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
}

void Update(int rt,int L,int R,int pos,int val){
	if(L==pos&&R==pos){
		node[rt].min=val;
		node[rt].max=val;
		return ;
	}
	int mid=(L+R)>>1;
	if(pos<=mid) Update(rt<<1,L,mid,pos,val);
	if(pos>mid) Update(rt<<1|1,mid+1,R,pos,val);
	PushUp(rt);
}

void Query(int rt,int L,int R,int l,int r){
	if(L==l&&R==r){
		minNum=min(minNum,node[rt].min);
		maxNum=max(maxNum,node[rt].max);
		return ;
	}
	int mid=(L+R)>>1;
	if(l>mid) Query(rt<<1|1,mid+1,R,l,r);
	else if(r<=mid) Query(rt<<1,L,mid,l,r);
	else{
		Query(rt<<1,L,mid,l,mid);
		Query(rt<<1|1,mid+1,R,mid+1,r);
	}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
#endif
	while(~scanf("%d%d",&n,&q)){
		build(1,1,n);
		int x;
		for(int i=1;i<=n;i++){
			scanf("%d",&x);
			Update(1,1,n,i,x);
		}
		int a,b;
		while(q--){
			scanf("%d%d",&a,&b);
			minNum=INF,maxNum=-INF;
			Query(1,1,n,a,b);
			printf("%d\n",maxNum-minNum);
		}
	}
	return 0;
}


你可能感兴趣的:(poj 3264 Balanced Lineup(RMQ && 线段树))