zoukankan      html  css  js  c++  java
  • POJ 3264 Balanced Lineup -- RMQ或线段树

    一段区间的最值问题,用线段树或RMQ皆可。两种代码都贴上:又是空间换时间。。

    RMQ 解法:(8168KB 1625ms)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <cstdlib>
    using namespace std;
    #define N 50003
    
    int a[N],dmin[N][20],dmax[N][20],n;
    
    void RMQ_init()
    {
        int i,j;
        for(i=1;i<=n;i++)
            dmin[i][0] = dmax[i][0] = a[i];
        for(j=1;(1<<j)<=n;j++)
        {
            for(i=1;i+(1<<j)-1<=n;i++)
            {
                dmin[i][j] = min(dmin[i][j-1],dmin[i+(1<<(j-1))][j-1]);
                dmax[i][j] = max(dmax[i][j-1],dmax[i+(1<<(j-1))][j-1]);
            }
        }
    }
    
    int RMQ(int l,int r)
    {
        int k = 0;
        while((1<<(k+1)) <= r-l+1)
            k++;
        return max(dmax[l][k],dmax[r-(1<<k)+1][k]) - min(dmin[l][k],dmin[r-(1<<k)+1][k]);
    }
    
    int main()
    {
        int q,i;
        while(scanf("%d%d",&n,&q)!=EOF)
        {
            for(i=1;i<=n;i++)
                scanf("%d",&a[i]);
            RMQ_init();
            while(q--)
            {
                int l,r;
                scanf("%d%d",&l,&r);
                if(l>r)
                    swap(l,r);
                printf("%d
    ",RMQ(l,r));
            }
        }
        return 0;
    }
    View Code

    线段树解法:(1172KB  2297ms)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <cstdlib>
    using namespace std;
    #define N 50003
    
    struct node
    {
        int maxi,mini;
    }tree[4*N];
    
    void pushup(int rt)
    {
        tree[rt].maxi = max(tree[2*rt].maxi,tree[2*rt+1].maxi);
        tree[rt].mini = min(tree[2*rt].mini,tree[2*rt+1].mini);
    }
    
    void build(int l,int r,int rt)
    {
        if(l == r)
        {
            scanf("%d",&tree[rt].maxi);
            tree[rt].mini = tree[rt].maxi;
            return;
        }
        int mid = (l+r)/2;
        build(l,mid,2*rt);
        build(mid+1,r,2*rt+1);
        pushup(rt);
    }
    
    int query_max(int l,int r,int aa,int bb,int rt)
    {
        if(aa>r || bb<l)
            return -100000;
        if(aa<=l && bb>=r)
            return tree[rt].maxi;
        int mid = (l+r)/2;
        return max(query_max(l,mid,aa,bb,2*rt),query_max(mid+1,r,aa,bb,2*rt+1));
    }
    
    int query_min(int l,int r,int aa,int bb,int rt)
    {
        if(aa>r || bb<l)
            return 100000000;
        if(aa<=l && bb>=r)
            return tree[rt].mini;
        int mid = (l+r)/2;
        return min(query_min(l,mid,aa,bb,2*rt),query_min(mid+1,r,aa,bb,2*rt+1));
    }
    
    int main()
    {
        int n,q,i;
        while(scanf("%d%d",&n,&q)!=EOF)
        {
            build(1,n,1);
            for(i=1;i<=q;i++)
            {
                int l,r;
                scanf("%d%d",&l,&r);
                if(l>r)
                    swap(l,r);
                printf("%d
    ",query_max(1,n,l,r,1)-query_min(1,n,l,r,1));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    指出在 spring aop 中 concern 和 cross-cutting concern 的不同之处?
    什么是 spring bean?
    Java 中,Serializable 与 Externalizable 的区别?
    spring DAO 有什么用?
    spring 支持集中 bean scope?
    Spring 应用程序有哪些不同组件?
    什么是切点JoinPoint?
    @Required 注解有什么用?
    用什么命令对一个文件的内容进行统计?(行号、单词数、 字节数) ?
    区分构造函数注入和 setter 注入?
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3582486.html
Copyright © 2011-2022 走看看