zoukankan      html  css  js  c++  java
  • 线段树维护区间最大值最小值

    poj3264

    对于每天挤奶,农民约翰的ñ奶牛(1≤ ñ ≤50,000)总是以相同的顺序排队。有一天,农夫约翰决定与一些母牛一起组织一场极限飞盘比赛。为简单起见,他将从挤奶阵容中选择一头连续的奶牛来玩游戏。但是,为了让所有的奶牛玩得开心,它们的身高不应相差太大。

    农夫约翰已经做过的Q(1≤ Q ≤200,000)奶牛的潜在群体和他们的高度(1个≤ 高度 ≤1,000,000)。对于每个组,他都需要您的帮助来确定该组中最矮和最高的母牛之间的身高差异。

    输入项

    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 ≤ A ≤ B ≤ N), 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

    题目大意就是:

    就是给你一个l,r让你求区间内的最大值减去最小值

    #include <iostream>
    #include <cstdio>
    #include  <cstring>
    #include  <algorithm>
    using namespace std;
    typedef long long ll;
    template <typename Tp>
    void read(Tp &x){
        x=0;char ch=1;int fh;
        while(ch!='-'&&(ch>'9'||ch<'0')){
            ch=getchar();
        }
        if(ch=='-'){
            fh=-1;ch=getchar();
        }else fh=1;
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+ch-'0';ch=getchar();
        }
        x*=fh;
    }
    inline char read1()
    {
        register char ch=getchar();
        while(ch<'A'||ch>'M')ch=getchar();
        return ch;
    }
    const int maxn=1e6+100;
    struct node{
        int l,r,ma,mi;
    }t[maxn];
    int a[maxn];
    int n,q,x,y,ans1,ans2;
    void build(int p,int l,int r){
        t[p].l=l,t[p].r=r;
        if(l==r){
            t[p].ma=t[p].mi=a[l];
            return ;
        }
        int mid=(t[p].l+t[p].r)>>1;    
        build(p<<1,l,mid);
        build((p<<1)+1,mid+1,r);
        t[p].ma=max(t[p<<1].ma,t[(p<<1)+1].ma);
        t[p].mi=min(t[p<<1].mi,t[(p<<1)+1].mi);
    }
    void query(int p,int l,int r){
        if(l<=t[p].l&&r>=t[p].r){
            ans1=max(ans1,t[p].ma);
            ans2=min(ans2,t[p].mi);
            return ;
        }
        int mid=(t[p].l+t[p].r)>>1;
        if(l<=mid){
            query(p<<1,l,r);
        }
        if(r>mid){
            query((p<<1)+1,l,r);
        }
    }
    int main(){
        read(n),read(q);
        for(int i=1;i<=n;i++){
            read(a[i]);
        }
        build(1,1,n);
        while(q--){
            read(x),read(y);
            ans1=0,ans2=0x3f3f3f3f;
            query(1,x,y);
            printf("%d
    ",ans1-ans2); 
        }
    } 
    #include <iostream>
    #include <cstdio>
    #include  <cstring>
    #include  <algorithm>
    using namespace std;
    typedef long long ll;
    template <typename Tp>
    void read(Tp &x){
        x=0;char ch=1;int fh;
        while(ch!='-'&&(ch>'9'||ch<'0')){
            ch=getchar();
        }
        if(ch=='-'){
            fh=-1;ch=getchar();
        }else fh=1;
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+ch-'0';ch=getchar();
        }
        x*=fh;
    }
    inline char read1()
    {
        register char ch=getchar();
        while(ch<'A'||ch>'M')ch=getchar();
        return ch;
    }
    const int maxn=1e6+100; 
    int z[maxn];
    struct node{
        int mi,ma;
    }a[maxn];
    void build(int p,int l,int r){
        if(l==r){
            a[p].ma=z[l],a[p].mi=z[l];
            return ;
        }
        int mid=(l+r)>>1;
        build(p<<1,l,mid);
        build((p<<1)+1,mid+1,r);
        a[p].mi=min(a[p<<1].mi,a[(p<<1)+1].mi);
        a[p].ma=max(a[p<<1].ma,a[(p<<1)+1].ma);
    }
    int find1(int p,int l,int r,int x,int y){
        if(x<=l&&r<=y){
            return a[p].ma;
        }
        int mid=(l+r)>>1;
        if(y<=mid){
            return find1(p<<1,l,mid,x,y);
        }
        else if(x>mid){
            return find1((p<<1)+1,mid+1,r,x,y);
        }
        else return max(find1(p<<1,l,mid,x,mid),find1((p<<1)+1,mid+1,r,mid+1,y));
    }
    int find2(int p,int l,int r,int x,int y){
        if(x<=l&&r<=y){
            return a[p].mi;
        }
        int mid=(l+r)>>1;
        if(y<=mid){
            return find2(p<<1,l,mid,x,y);
        }
        else if(x>mid){
            return find2((p<<1)+1,mid+1,r,x,y);
        }
        else return min(find2(p<<1,l,mid,x,mid),find2((p<<1)+1,mid+1,r,mid+1,y));
    }
    int main(){
        int n,q;
        int x,y;
        while(~scanf("%d%d",&n,&q)){
            memset(a,0,sizeof(a));
            for(int i=1;i<=n;i++){
                scanf("%d",&z[i]);
            }
            build(1,1,n);
            while(q--){
                scanf("%d%d",&x,&y);
                printf("%d
    ",find1(1,1,n,x,y)-find2(1,1,n,x,y));
            }
        }
        return 0; 
    } 

     

  • 相关阅读:
    数组的顺序存储表示
    CF538G Berserk Robot
    【LGR-077】洛谷 10 月月赛 I Div.1 && P6854 Tram
    [THUPC2019]找树
    CF536D Tavas in Kansas
    luogu「EZEC-4.5」子序列
    2020.8.7
    拉格朗日反演
    2020.8.6
    初赛复习
  • 原文地址:https://www.cnblogs.com/lipu123/p/13688081.html
Copyright © 2011-2022 走看看