zoukankan      html  css  js  c++  java
  • POJ-2452-Sticks Problem(二分+RMQ)

    Time Limit: 6000MS   Memory Limit: 65536K

    题目链接:http://poj.org/problem?id=2452

    Description

    Xuanxuan has n sticks of different length. One day, she puts all her sticks in a line, represented by S1, S2, S3, ...Sn. After measuring the length of each stick Sk (1 <= k <= n), she finds that for some sticks Si and Sj (1<= i < j <= n), each stick placed between Si and Sj is longer than Si but shorter than Sj. 

    Now given the length of S1, S2, S3, …Sn, you are required to find the maximum value j - i.

    Input

    The input contains multiple test cases. Each case contains two lines. 
    Line 1: a single integer n (n <= 50000), indicating the number of sticks. 
    Line 2: n different positive integers (not larger than 100000), indicating the length of each stick in order.

    Output

    Output the maximum value j - i in a single line. If there is no such i and j, just output -1.

    Sample Input

    4
    5 4 3 6
    4
    6 5 4 3
    

    Sample Output

    1
    -1

    二分的姿势很重要。。。。
    题目大意:多组输入,找到一对点(i,j)其中i<j,使得区间[i+1,j-1]中所有的数严格大于a[i],严格小于a[j]。要你确定最大的j-i。如果没有则输出-1;

    我们可以枚举点i,然后往右找,二分+RMQ找到点k,使得a[k]<a[i],然后我们在区间[i+1,k-1]中找到最大值坐标j,如果a[j]>a[i]那么我们更新答案就好了。
    这里要注意一下二分的姿势,当l==r的时候直接return l;然后还有一些其他的姿势调整。。。

    以下是AC代码:
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int mac=5e4+10;
    
    int a[mac],mi[mac][25],mx[mac][25];
    
    int _min(int l,int r)
    {
        return a[l]>a[r]?r:l;
    }
    
    int _max(int l,int r)
    {
        return a[l]>a[r]?l:r;
    }
    
    void get_rmq(int n)
    {
        for (int i=1; i<=n; i++) mi[i][0]=mx[i][0]=i;
        for (int j=1; (1<<j)<=n; j++)
            for (int i=1; i+(1<<j)-1<=n; i++){
                mi[i][j]=_min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]);
                mx[i][j]=_max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]);
            }
    }
    
    int rmq(int l,int r,int mk)
    {
        int k=0;
        while (1<<(k+1)<=(r-l+1)) k++;
        int ansmi=_min(mi[l][k],mi[r-(1<<k)+1][k]);
        int ansmx=_max(mx[l][k],mx[r-(1<<k)+1][k]);
        if (mk) return ansmx;
        return ansmi;
    }
    
    int ok(int l,int r)
    {
        int ll=l+1,rr=r,mid;
        while (ll<=rr){
            if (ll==rr) return ll;
            mid=(ll+rr)>>1;
            if (a[rmq(ll,mid,0)]<a[l]) 
                rr=mid;
            else ll=mid+1;
        }
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int n;
        while (~scanf ("%d",&n)){
            int ans=0;
            for (int i=1; i<=n; i++){
                scanf ("%d",&a[i]);
            }
            get_rmq(n);
            for (int i=1; i+ans<=n; i++){
                int r=ok(i,n);
                int k=rmq(i,r,1);
                if (a[i]<a[k]) ans=max(ans,k-i);
            }
            if (!ans) printf("-1
    ");
            else printf("%d
    ",ans);
        }
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    TopCoder<SRM>上的一道1100分的题目解析附代码
    《算法导论》思考题15-2 整齐打印
    《算法导论》思考题15-1 双调欧几里得旅行商问题(动态规划)
    <ReversingEngineering>关于windows32位系统下的dll注入技术经验汇
    实现一个EventEmitter类,这个类包含以下方法: on/ once/fire/off
    [Jquery 插件]活动倒计时,可同步服务器时间,倒计时格式随意设置
    阻止a标签跳转四种方法 兼容各大浏览器(包括IE)
    git常用操作 配置用户信息、拉取项目、提交代码、分支操作、版本回退...
    nrm npm源管理利器
    Element UI 框架搭建
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/12196268.html
Copyright © 2011-2022 走看看