MT3024 max=min

简介: MT3024 max=min

61a508aa527546f593516916218e24e3.jpg

样例 1

输入:

6

1 2 3 2 1 4

6 7 1 2 3 2

输出:

2

备注

1≤n≤10^6,1≤ai,bi≤10^9。

思路:

(1)使用ST表。

ST表(Sparse Table)是一种用于高效处理区间查询的数据结构。它可以在O(1)的时间复杂度内回答某一区间的最值查询(最小值、最大值等)。ST表使用动态规划的思想,通过预处理的方式来快速计算出各个区间的最值。

(2)使用二分。因为此题具有单调性:随着放入数组的数越多,最大值一定非递减。最小值一定非递增。如果固定右端点r,则向左看,最大值从l->r呈阶梯状递增,最小值从l->r呈阶梯状递减,其中一定有交点使最小值=最大值。因为是阶梯状递增和递减,所以交点为横着的一条线段,即l的范围为此线段的范围。

所以每次枚举r,找l的范围并保存在答案中。找l的范围即找max=min,用二分来找。

此题代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, a[N], b[N], mn[N][20], mx[N][20], Lg[N], l, r, mid, ans;
void pre()
{
    Lg[1] = 0;
    for (int i = 2; i <= n; i++)
    {
        Lg[i] = Lg[i >> 1] + 1;
    }
}
void ST_create()
{ // 创建ST表
    for (int i = 1; i <= n; i++)
    {
        mx[i][0] = a[i], mn[i][0] = b[i];
    }
    for (int j = 1; j <= Lg[n]; j++)
    {
        for (int i = 1; i <= n - (1 << j) + 1; i++)
        {
            mx[i][j] = max(mx[i][j - 1], mx[i + (1 << (j - 1))][j - 1]);
            mn[i][j] = min(mn[i][j - 1], mn[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int ST_qmax(int l, int r)
{ // ST表求max
    int k = Lg[r - l + 1];
    return max(mx[l][k], mx[r - (1 << k) + 1][k]);
}
int ST_qmin(int l, int r)
{ // ST表求min
    int k = Lg[r - l + 1];
    return min(mn[l][k], mn[r - (1 << k) + 1][k]);
}
 
int findl(int i)
{ // l的范围左边界
    int l = 1, r = i, mid, ans = 0, minn, maxn;
    while (l <= r)
    {
        mid = (l + r) / 2;
        maxn = ST_qmax(mid, i), minn = ST_qmin(mid, i);
        if (maxn <= minn)
        {
            ans = mid, r = mid - 1;
        }
        else
            l = mid + 1;
    }
    return ans;
}
int findr(int i) // i为固定的枚举的右边界
{                // l的范围右边界
    int l = 1, r = i, mid, ans = 0, minn, maxn;
    while (l <= r) // 二分
    {
        mid = (l + r) / 2;
        maxn = ST_qmax(mid, i), minn = ST_qmin(mid, i);
        if (maxn >= minn)
        {
            ans = mid, l = mid + 1;
        }
        else
            r = mid - 1;
    }
    return ans;
}
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= n; i++)
        cin >> b[i];
    pre();
    ST_create();
    for (int i = 1; i <= n; i++)
    { // 枚举右端点i
        // 对于每个i,求l的范围findl和findr
        int j = findl(i);
        if (j < 1 || j > i)
        {
            continue;
        }
        int k = findr(i);
        ans += k - j + 1;
    }
    cout << ans;
    return 0;
}


相关文章
|
5月前
|
SQL 数据库
MAX() 函数
MAX() 函数
52 6
|
移动开发 安全 JavaScript
MAX4/11/03/016/08/1/1/00 MAX-4/11/01/008/08/1/1/00
MAX4/11/03/016/08/1/1/00 MAX-4/11/01/008/08/1/1/00
54 0
|
6月前
|
编译器 C++
C++ max函数与min函数
C++ max函数与min函数
217 0
C400/A8/1/1/1/00 MAX-4/11/03/128/99/1/0/00
C400/A8/1/1/1/00 MAX-4/11/03/128/99/1/0/00
38 0
|
C++ 容器
STL之max,min,max_element(),min_element()的对比应用
STL之max,min,max_element(),min_element()的对比应用
|
算法 C++
10min快速回顾C++语法(一)
本系列文章旨在短时间内回顾C/C++语法中的重点与易错点,巩固算法竞赛与写题过程中常用的语法知识,精准地解决学过但有遗忘的情况,为算法刷题打下坚实的基础。
122 0
|
Oracle 关系型数据库 索引
20180316不使用INDEX FULL SCAN (MIN/MAX)
[20180316]为什么不使用INDEX FULL SCAN (MIN/MAX).txt --//链接:http://www.itpub.net/thread-2100456-1-1.
1191 0