线段树练习POJ 3264

问题:有n只奶牛排成一列,他们有各自的身高Hi,有Q个区间,分别求出这些区间中最高和最矮的差值。

Sample Input

6 3 (六只奶牛,下面分别是它们的身高,3个区间)
1
7
3
4
2
5
1 5
4 6
2 2
Sample Output

6
3
0

import java.io.StreamTokenizer;   
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;

class tree{ //线段树节点
int left,right,maxvalue,minvalue;
}

public class Main{
tree[] tt;//线段树,用数组实现

int height[];//奶牛身高

public Main(int[] height){
this.height=height;
tt=new tree[131070];
for(int i=0;i<131070;i++)
//数组大小的计算参看:http://128kj.iteye.com/blog/1739064
tt[i]=new tree();
}

private void built_tree(int lp,int rp,int pos){ //构建以pos为根的线段树
tt[pos].left=lp;
tt[pos].right=rp;
if(lp==rp){
tt[pos].maxvalue=height[rp];
tt[pos].minvalue=height[lp];
return ;
}
int mid=(tt[pos].left+tt[pos].right)>>1;
built_tree(lp,mid,pos<<1);
built_tree(mid+1,rp,pos<<1|1);
tt[pos].maxvalue=Math.max(tt[pos<<1].maxvalue,tt[pos<<1|1].maxvalue);
tt[pos].minvalue=Math.min(tt[pos<<1].minvalue,tt[pos<<1|1].minvalue);
}

//找[lp,rp]上的最大值
private int findmax(int lp,int rp,int pos){
if(tt[pos].left==lp&&tt[pos].right==rp){
return tt[pos].maxvalue;
}

int mid=(tt[pos].left+tt[pos].right)>>1;
if(rp<=mid){
return findmax(lp,rp,pos<<1);
}
else if(lp>mid)
return findmax(lp,rp,pos<<1|1);
else{
return Math.max( findmax(lp,mid,pos<<1), findmax(mid+1,rp,pos<<1|1));
}
}

//找[lp,rp]上的最小值
private int findmin(int lp,int rp,int pos){
if(tt[pos].left==lp&&tt[pos].right==rp){
return tt[pos].minvalue;
}
int mid=(tt[pos].left+tt[pos].right)>>1;
if(rp<=mid)
return findmin(lp,rp,pos<<1);
else if(lp>mid)
return findmin(lp,rp,pos<<1|1);
else
return Math.min( findmin( lp,mid,pos<<1 ),findmin( mid+1,rp,pos<<1|1 ) );
}

public static void main(String args[]) throws IOException{
StreamTokenizer st = new StreamTokenizer(new BufferedReader(
new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

while(st.nextToken() != StreamTokenizer.TT_EOF) {

int n=(int) st.nval;
st.nextToken();
int q=(int) st.nval;
int[] height=new int[n+1];
for(int i=1;i<=n;++i){
st.nextToken();
height[i]=(int) st.nval;
}

Main ma=new Main(height);
ma.built_tree(1,n,1);
int x,y;
while(q-->0){
st.nextToken();
x=(int) st.nval;
st.nextToken();
y=(int) st.nval;
int mmax=ma.findmax(x,y,1);
int mmin=ma.findmin(x,y,1);
System.out.printf("%d\n",mmax-mmin);
}
out.flush();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值