POJ 3264 Balanced Lineup

给定Q (1 ≤ Q ≤ 200,000)个数A1,A2 … AQ,,多次求任一区间Ai – Aj中最大数和最小数的差。

Sample Input
6 3 //6个数,3次个查询
1
7
3
4
2
5
1 5
4 6
2 2

Sample Output

6

3

0

感悟:

遵循三个过程:

  1. 建树过程
  2. 存输过程
  3. 查询过程

每一个都要用到比较和递归。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct Node{
	int L,R;
	int min,max;
	int mid(){
		return (L+R)/2;
	}
}tree[800010];
int minV=(1<<30);
int maxV=-(1<<30);
void BuiltTree(int root,int L,int R){
	tree[root].L=L;
	tree[root].R=R;
	tree[root].min=(1<<30);
	tree[root].max=-(1<<30);
	if(L!=R){
		BuiltTree(2*root+1,L,(L+R)/2);
		BuiltTree(2*root+2,(L+R)/2+1,R);	
	}	
}
void Insert(int root,int i,int t){
	if(tree[root].L==tree[root].R){
		tree[root].min=tree[root].max=t;
		return;
	}
	tree[root].max=max(tree[root].max,t);
	tree[root].min=min(tree[root].min,t);
	if(i<=tree[root].mid()){
		Insert(2*root+1,i,t);
	}else{
		Insert(2*root+2,i,t);
	}
}
void Query(int root,int s,int e){
	if(tree[root].min>=minV&&tree[root].max<=maxV){
		return;
	}
	if(tree[root].L==s&&tree[root].R==e){
		minV=min(minV,tree[root].min);
		maxV=max(maxV,tree[root].max);
		return;
	}
	if(e<=tree[root].mid()){
		Query(2*root+1,s,e);
	}else if(s>tree[root].mid()){//
		Query(2*root+2,s,e);
	}else{
		Query(2*root+1,s,tree[root].mid());
		Query(2*root+2,tree[root].mid()+1,e);
	}
}
int main(){
	int n,q;
	scanf("%d %d",&n,&q);
	BuiltTree(0,1,n);
	for(int i=1;i<=n;i++){
		int t;
		scanf("%d",&t);
		Insert(0,i,t);
	}
	for(int j=1;j<=q;j++){
		int s,e;
		scanf("%d %d",&s,&e);
		minV=(1<<30);
		maxV=-(1<<30);
		Query(0,s,e);
		printf("%d\n",maxV-minV);
	}
	return 0;
}

注意:不能用c++的输入输出函数,铁定超时

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值