• 51nod 1275 连续子段的差异


    题目看这里

    若[i,j]符合要求,那么[i,j]内的任何连续的子段都是符合要求的。我们可以枚举i,找到能合格的最远的j,然后ans+=(j-i+1)。

    那么问题就转换成了:在固定i的情况下,如何判断j范围内是否合法?若[i,j]内的max-min<=K自然就合法。于是相当于求区间内的最值问题。这个可以用单调队列解决。

    下面对代码给出一些解释:

    1:为何是j-i而非j-i+1?因为当不合法时区间相当于[i,j),左闭右开,数量是i-j即可。

    2:后面的两行如if (dqB.front() == i) dqB.pop_front(); 什么作用?因为要枚举i,所以到了下一个i的时候,若前面的i还在队列中,要去掉。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxN=5e4+5;
    int N, M, K, T;
    int g[maxN];
    deque<int> dqB, dqS;
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.in", "r", stdin);
    #endif
        scanf("%d%d", &N, &K);
        for (int i = 1; i <= N; ++i)
            scanf("%d", g + i);
        int ans = 0;
        for (int i = 1, j = 1; i <= N; ++i) {
            while (j <= N) {
                while (dqS.size() && g[dqS.back()] >= g[j]) dqS.pop_back();
                dqS.push_back(j);
                while (dqB.size() && g[dqB.back()] <= g[j]) dqB.pop_back();
                dqB.push_back(j);
    
                if (g[dqB.front()] - g[dqS.front()] > K)
                    break;
                ++j;
            }
            ans += (j - i);
            if (dqS.front() == i) dqS.pop_front();
            if (dqB.front() == i) dqB.pop_front();
        }
        printf("%d", ans);
        return 0;
    }

    附上别的相关的博客

  • 相关阅读:
    第二次作业
    第一次作业
    第五次作业
    第四次作业
    第三次作业
    第二次作业
    第一次作业
    HTML标签分类
    HTML属性与事件的搭配使用
    HTML全局属性和全局事件属性
  • 原文地址:https://www.cnblogs.com/Rosebud/p/9531591.html
Copyright © 2020-2023  润新知