zoukankan      html  css  js  c++  java
  • poj2452

    题意:给出n个互不相同的数字,要求一个最大的子段,使得该子段内所有数(除了两端以外),值都在两端的数字之间,且不能等于两端的数。

    分析:先对整个数组分别构造最大值RMQ和最小值RMQ的st数组。然后,枚举子段起点,对于每个起点求出这个起点是区间最小值的最远终点(用二分查找)。然后在这个区间内找到最大值位置,从起点到最大值位置这个区间就是起点所对应的符合题意的最大区间。枚举过所有的起点之后,结果就求出来了。

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    using namespace std;
    
    #define inf 0x3f3f3f3f
    #define maxn 50005
    
    int n;
    int f[maxn];
    int st1[maxn][32];
    int st2[maxn][32];
    int d[32];
    
    void InitRMQ1(int f[], int n, int st[][32])
    {
        int i, j;
        for (d[0] = 1, i = 1; i < 21; i++)
            d[i] = 2 * d[i - 1];
        for (i = 0; i < n; i++)
            st[i][0] = i;
        int k = int(log(double(n))/log(2)) + 1;
        for (j = 1; j < k; j++)
            for (i = 0; i < n; i++)
                if (i + d[j - 1] - 1 < n)
                {
                    if (f[st[i][j - 1]] < f[st[i + d[j - 1]][j - 1]])
                        st[i][j] = st[i + d[j - 1]][j - 1];
                    else
                        st[i][j] = st[i][j - 1];
                }
                else
                    break;
    }
    
    int query1(int x, int y, int st[][32])
    {
        int k = int(log(double(y - x + 1)) / log(2.0));
        if (f[st[x][k]] < f[st[y - d[k] + 1][k]])
            return st[y - d[k] + 1][k];
        return st[x][k];
    }
    
    void InitRMQ2(int f[], int n, int st[][32])
    {
        int i, j;
        for (d[0] = 1, i = 1; i < 21; i++)
            d[i] = 2 * d[i - 1];
        for (i = 0; i < n; i++)
            st[i][0] = i;
        int k = int(log(double(n))/log(2)) + 1;
        for (j = 1; j < k; j++)
            for (i = 0; i < n; i++)
                if (i + d[j - 1] - 1 < n)
                {
                    if (f[st[i][j - 1]] > f[st[i + d[j - 1]][j - 1]])
                        st[i][j] = st[i + d[j - 1]][j - 1];
                    else
                        st[i][j] = st[i][j - 1];
                }
                else
                    break;
    }
    
    int query2(int x, int y, int st[][32])
    {
        int k = int(log(double(y - x + 1)) / log(2.0));
        if (f[st[x][k]] > f[st[y - d[k] + 1][k]])
            return st[y - d[k] + 1][k];
        return st[x][k];
    }
    
    void input()
    {
        for (int i = 0; i < n; i++)
            scanf("%d", &f[i]);
    }
    
    
    int binary_search(int a)
    {
        int l = a, r = n - 1;
        while (l < r)
        {
            int mid = (l + r) / 2 + ((l + r) & 1);
            if (query2(a, mid, st2) == a)
                l = mid;
            else
                r = mid - 1;
        }
        return l;
    }
    
    int work()
    {
        int ret = 0;
        for (int i = 0; i < n; i++)
        {
            int r = query1(i, binary_search(i), st1);
            ret = max(ret, r - i);
        }
        if (ret == 0)
            return -1;
        return ret;
    }
    
    int main()
    {
        //freopen("t.txt", "r", stdin);
        while (~scanf("%d", &n))
        {
            input();
            InitRMQ1(f, n, st1);
            InitRMQ2(f, n, st2);
            printf("%d\n", work());
        }
        return 0;
    }
  • 相关阅读:
    169. Majority Element
    283. Move Zeroes
    1331. Rank Transform of an Array
    566. Reshape the Matrix
    985. Sum of Even Numbers After Queries
    1185. Day of the Week
    867. Transpose Matrix
    1217. Play with Chips
    766. Toeplitz Matrix
    1413. Minimum Value to Get Positive Step by Step Sum
  • 原文地址:https://www.cnblogs.com/rainydays/p/2584576.html
Copyright © 2011-2022 走看看