• HDU 5289


    Tom owns a company and he is the boss. There are n staffs which are numbered from 1 to n in this company, and every staff has a ability. Now, Tom is going to assign a special task to some staffs who were in the same group. In a group, the difference of the ability of any two staff is less than k, and their numbers are continuous. Tom want to know the number of groups like this.

    InputIn the first line a number T indicates the number of test cases. Then for each case the first line contain 2 numbers n, k (1<=n<=100000, 0<k<=10^9),indicate the company has n persons, k means the maximum difference between abilities of staff in a group is less than k. The second line contains n integers:a[1],a[2],…,a[n](0<=a[i]<=10^9),indicate the i-th staff’s ability.OutputFor each test,output the number of groups.Sample Input

    2
    4 2
    3 1 2 4
    10 5
    0 3 4 5 2 1 6 7 8 9

    Sample Output

    5
    28

    Hint

    First Sample, the satisfied groups include:[1,1]、[2,2]、[3,3]、[4,4] 、[2,3] 

    题意: 求出所有满足最大值与最小值的差小于k的子区间的个数。

    这个人的思路写的比较清晰: https://blog.csdn.net/maxichu/article/details/47612497


    用两个单调队列维护最大值与最小值, 然后就是枚举左端点的过程。

    设两个指针i,j 并让他们从头扫到尾,这样是O(n)的复杂度, 如果不知道单调队列是啥就自行百度吧。

    [j, i-1]是当前处理的区间。将第 i 个元素加入后如果最大值-最小值 >= k 就说明[j,i]不可行。那么[j,k](k>x && k<=n)同样是不可行的。
    所以这时我们就处理完了所有以 j 做为左端点的区间了,开始更新j 并统计。


    #include<cstdio>
    #include<queue>
    using namespace std;
    #define ll long long
    deque<int>Max, Min;
    int arr[100005];
    
    int main(){
        int t, n, k;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&k);
            for(int i=0;i<n;i++){
                scanf("%d",&arr[i]);
            }
            int i = 0, j = 0;
            ll ans = 0;
            Max.clear();Min.clear();
            for(;i<n;i++){
                while(!Max.empty() && Max.back() < arr[i])
                    Max.pop_back();
                Max.push_back(arr[i]);
                while(!Min.empty() && Min.back() > arr[i])
                    Min.pop_back();
                Min.push_back(arr[i]);
                while(!Max.empty() && !Min.empty()
                      && Max.front()-Min.front() >= k){
                    ans += (i-j);
                    // 这是所有以 j 为左端点的区间的数量(右端点为i-1)
                    if(Max.front() == arr[j])Max.pop_front();
                     // 后续的处理中 j 不在区间中, 所以要将arr[j]取出
                    if(Min.front() == arr[j])Min.pop_front();
                    j++;// 更新 j
                }
            }
            while(j<n){ // [j, n] 是个可行解
                ans += i-j;
                j++;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code


  • 相关阅读:
    iphone的苹果式营销体会
    上海自驾游之水博园游记
    2011上海车展参观记(多图)
    一部烂电影《让子弹飞》
    坚持自己读罗永浩《我的奋斗》感悟
    转:心理测试
    我们只要世界第一
    一篇小学课文
    iphone 4 初体验
    Setting Expires and CacheControl: maxage headers for static resources in ASP.NET
  • 原文地址:https://www.cnblogs.com/kongbb/p/10746636.html
Copyright © 2020-2023  润新知