poj 3264

#include<iostream>
#include<cstdio>
using namespace std;
const int INF=0x3f3f3f3f;
int minV=INF;
int maxV=-INF;
struct Node//每一个根节点保存它的所有子节点的最大值,最小值,L,R表示这个根结点包含的范围
{
    int L,R;
    int minV,maxV;
    int Mid()
    {
        return (L+R)/2;
    }
};
Node tree[800010];//数组的大小必须是元素总数目的三倍到四倍,因为存储的时候开头是根节点,后面才是叶子节点,有n个叶子
void BuildTree(int root,int L,int R)
{
    tree[root].L=L;
    tree[root].R=R;
    tree[root].minV=INF;
    tree[root].maxV=-INF;
    if(L!=R){
        BuildTree(2*root+1,L,(L+R)/2);
        BuildTree(2*root+2,(L+R)/2+1,R);
    }
}
void Insert(int root,int i,int v)//将某一个点插入到线段树中
{
    if(tree[root].L==tree[root].R)//如果找到叶子节点就把数据更新
    {
         tree[root].minV=v;
         tree[root].maxV=v;
         return;
    }
    tree[root].minV=min(tree[root].minV,v);如果是根结点就把最大最小值更新
    tree[root].maxV=max(tree[root].maxV,v);
    if(i<=tree[root].Mid())//并从根节点进行左右子节点的寻找需要插入的位置
        Insert(2*root+1,i,v);
    else
        Insert(2*root+2,i,v);
}
void Query(int root,int s,int e)
{
    if(tree[root].minV>=minV&&tree[root].maxV<=maxV)//当前结点包含的所有数据的最大值比已经找的的最大值小或者最小值比已经找的最小值大
        return;
    if(tree[root].L==s&&tree[root].R==e)//按线段树每一步都分成二分之一的范围向下寻找的时候一定会找到一步:走到了叶子节点或者正好找到了要寻找的区间
    {                                   
        minV=min(minV,tree[root].minV);
        maxV=max(maxV,tree[root].maxV);
        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,h;
    int i,j,k;
    scanf("%d%d",&n,&q);
    BuildTree(0,1,n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&h);
        Insert(0,i,h);
    }
    for(i=0;i<q;i++)
    {
        int s,e;
        scanf("%d%d",&s,&e);
        minV=INF;
        maxV=-INF;
        Query(0,s,e);
        printf("%d\n",maxV-minV);
    }
    return 0;
}

For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.

Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.

Input

Line 1: Two space-separated integers, N and Q.
Lines 2.. N+1: Line i+1 contains a single integer that is the height of cow i
Lines N+2.. N+ Q+1: Two integers A and B (1 ≤ ABN), representing the range of cows from A to B inclusive.

Output

Lines 1.. Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.

Sample Input

6 3
1
7
3
4
2
5
1 5
4 6
2 2

Sample Output

6
3
0

这是北京大学暑期训练课ppt里面的代码,不愧是好大学,感觉做ppt的用心程度上就不是一般大学能比的

今天刚刚接触线段树,对着代码写了一遍并进行了思考,写的真的很好

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值