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

    题目链接:

    https://cn.vjudge.net/problem/POJ-2452

    题目大意:

    给出一个数组a,求最大的j-i满足 i<j && a[i] ... a[j]中最大值为a[j],最小值为a[i]。

    思路:

    可以枚举i,然后二分找出满足的最大的j

    首先,先二分找出最大的r,满足从a[i]到a[j]的最小值为a[i]。根据单调性可以二分找出来

    然后从i-r找出最大值的下标就可以了。

    二分的时候,需要多次求出区间最大最小值,用ST表预处理出来。

    也可以用线段树,不过更慢。时间可以卡着过

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
     6 #define Max(a, b) (a) > (b) ? (a) : (b)
     7 #define Min(a, b) (a) < (b) ? (a) : (b)
     8 #define Mem(a) memset(a, 0, sizeof(a))
     9 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
    10 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂
    11 using namespace std;
    12 inline int read()
    13 {
    14     int x=0,f=1;char ch=getchar();
    15     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    16     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    17     return x*f;
    18 }
    19 
    20 typedef long long ll;
    21 const int maxn = 50000 + 10;
    22 const int MOD = 1000000007;//const引用更快,宏定义也更快
    23 
    24 int a[maxn];
    25 int rmq_min[maxn][20], rmq_max[maxn][20];
    26 int n;
    27 
    28 void ST_init()
    29 {
    30     for(int i = 1; i <= n; i++)rmq_max[i][0] = rmq_min[i][0] = a[i];//下标从1-n
    31     for(int j = 1; (1 << j) <= n; j++)
    32     {
    33         for(int i = 1; i + (1 << j) - 1 <= n; i++)
    34             rmq_min[i][j] = Min(rmq_min[i][j - 1], rmq_min[i + (1 << (j - 1))][j - 1]);
    35     }
    36     for(int j = 1; (1 << j) <= n; j++)
    37     {
    38         for(int i = 1; i + (1 << j) - 1 <= n; i++)
    39             rmq_max[i][j] = Max(rmq_max[i][j - 1], rmq_max[i + (1 << (j - 1))][j - 1]);
    40     }
    41 }
    42 inline int query_Min(int l, int r)
    43 {
    44     int k = 0;
    45     while((1 << (k + 1)) <= r - l + 1)k++;
    46     return Min(rmq_min[l][k], rmq_min[r - (1 << k) + 1][k]);
    47 }
    48 inline int query_Max(int l, int r)
    49 {
    50     int k = 0;
    51     while((1 << (k + 1)) <= r - l + 1)k++;
    52     return Max(rmq_max[l][k], rmq_max[r - (1 << k) + 1][k]);
    53 }
    54 int main()
    55 {
    56     while(scanf("%d", &n) != EOF)
    57     {
    58         for(int i = 1; i <= n; i++)a[i] = read();
    59         ST_init();
    60         int ans = -1;
    61         for(int i = 1; i < n; i++)
    62         {
    63             int l = i, r = n, ansr = -1;
    64             while(l <= r)//二分 找最右端满足区间最小值为a[i]的下标
    65             {
    66                 int mid = (l + r) / 2;
    67                 if(query_Min(i, mid) == a[i])
    68                     ansr = mid, l = mid + 1;
    69                 else r = mid - 1;
    70             }
    71             if(ansr > i)//再次二分,找到最大值点的下标
    72             {
    73                 int tmp = query_Max(i, ansr);
    74                 l = i, r = ansr;
    75                 ansr = -1;
    76                 while(l <= r)
    77                 {
    78                     int mid = (l + r) / 2;
    79                     if(query_Max(i, mid) == tmp)r = mid - 1, ansr = mid;
    80                     else l = mid + 1;
    81                 }
    82                 if(ansr > i)ans = Max(ans, ansr - i);
    83             }
    84         }
    85         printf("%d
    ", ans);
    86     }
    87     return 0;
    88 }
  • 相关阅读:
    算法设计策略
    挖金矿
    寻找假币
    循环赛日程表
    【三分钟视频教程】iOS开发中 Xcode 报 apple-o linker 错误的#解决方案#
    iOS问题#解决方案#之关于“application/x-www-form-urlencoded;charset=utf-8” not supported
    【两分钟教程】如何为博客园添加QQ咨询效果
    【两分钟教程】如何更改Xcode项目名称
    iOS数据库操作之coredata详细操作步骤
    svn使用笔记
  • 原文地址:https://www.cnblogs.com/fzl194/p/9562603.html
Copyright © 2011-2022 走看看