• 牛客多校第五场 K King of Range


    题意:

    给定一个(n)个数得序列(a_i),给定(m)个询问,每次给出一个(k),寻找有多少个区间([l, r])中最大值与最小值之差严格大于(k)

    思路:

    可以发现,如果已经知道一个区间最大值与最小值严格大于k之后,那么我们便可以往从两头这个区间随意加数并且会对答案有贡献:
    如果加一个比最大值大的或者比最小值小的数,那么这个区间差值还是严格大于(k)
    如果加一个介于最大值最小值之间的数,那么这个区间差值不会发生变化。
    那么发现这一点之后便可以使用双指针寻找区间了,那么怎么维护区间最值呢(比赛的时候想到了用双指针但没想到怎么维护最值),(ST)表就派上用场了,那么我们固定一个(i),让(j)去寻找即可,找到第一个合适的区间就可以停下了,那么j往后的所有数都可以加到这个区间中而对答案产生贡献就是(n - j + 1)

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1E5 + 10, M = 18;
    
    int n, m, k;
    int w[N];
    int f1[N][M], f2[N][M];
    int lg[N];
    
    void init() {
        for (int j = 0; j < M; j++) {
            for (int i = 1; i + (1 << j) - 1 <= n; i++) {
                if (!j) f1[i][j] = w[i], f2[i][j] = w[i];
                else {
                    f1[i][j] = max(f1[i][j - 1], f1[i + (1 << j - 1)][j - 1]);
                    f2[i][j] = min(f2[i][j - 1], f2[i + (1 << j - 1)][j - 1]);
                }
            }
        }
    }
    
    bool check(int l, int r, int k) {
        int len = r - l + 1;
        int d = lg[len];
        int maxD = max(f1[l][d], f1[r - (1 << d) + 1][d]);
        int minD = min(f2[l][d], f2[r - (1 << d) + 1][d]);
        return maxD - minD > k;
    }
    
    int main() {
        //ios::sync_with_stdio(false); cin.tie(0);
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
        
        lg[2] = 1;
        for(int i=3;i<=n;i++) {
            lg[i] = lg[i / 2] + 1;
        }
        
        init();
    
        while (m--) {
            long long res = 0;
            int k; scanf("%d", &k);
            for (int l = 1, r = 1; l <= n; l++) {
                while (!check(l, r, k) && r <= n && l <= r) r++;
                if (r <= n) res += n - r + 1;
            }
            printf("%lld
    ", res);
        }
    
        return 0;
    }
    

    值得一提的是,用库函数(log)函数的效率有点不行,会被卡,所以还是乖乖预处理一个(log)数组吧。

  • 相关阅读:
    hadoop再次集群搭建(3)-如何选择相应的hadoop版本
    48. Rotate Image
    352. Data Stream as Disjoint Interval
    163. Missing Ranges
    228. Summary Ranges
    147. Insertion Sort List
    324. Wiggle Sort II
    215. Kth Largest Element in an Array
    快速排序
    280. Wiggle Sort
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/15087212.html
Copyright © 2020-2023  润新知