hdu 5289

来源:互联网 发布:ansys15.0软件 编辑:程序博客网 时间:2024/06/04 00:44

Assignment


Problem Description
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.
 

Input
In 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.
 

Output
For each test,output the number of groups.
 

Sample Input
24 23 1 2 410 50 3 4 5 2 1 6 7 8 9
 

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

题目大意:    在区间内任意两个数的差值不超过k  求出在n个数的数组里面 这样的区间有多少个

思      路 :  完全没有接触过的单调队列,学习了一下,设计棒棒哒。
                    
                     单调队列分为当前递增队列和当前递减队列,注意都是在当前的情况下。
                     递增队列值存在到目前为止所有的递增数,递减队列是以当前数为最小的情况下存储的值。
       
                    利用Front指针可以指向此时区间的起点,并且在不断的更新当中。
                   当出现此时的最大值与最小值相比较后不符合条件k'的情况,此时需要更新两个队列的指针使他们指向
                   新的起点即下一个区间的开始,同时得出上一个区间是否存在。

代码如下,内含详细解释
#include<cstring>#include<cstdio>#include<iostream>#include<algorithm>using namespace std;#define ll long longconst int N=1e5+10;ll t,n,k;ll data[N];void slove(){    ll ans=1,Front=1;   //计数器 当前已存data[1]    ll head1=0,head2=0,tail1=0,tail2=0;//两个队列的头尾指针      ll up[N],down[N];    up[tail1++]=1,down[tail2++]=1; //放入第一个数据后进行比较    for(int i=2;i<=n;i++){         //更新递增队列  删除>=data[i]的数            while(head1<tail1&&data[up[tail1-1]]>=data[i])              tail1--;         up[tail1++]=i; //存储i         //更新递减队列  删除<=data[i]的数         while(head2<tail2&&data[down[tail2-1]]<=data[i])             tail2--;         down[tail2++]=i; //存储i         //但出现不符合条件的情况是  各部分都需要更新         while(data[down[head2]]-data[up[head1]]>=k){             //递增队列的指针如果同步于当前指针需要更新                if(Front==up[head1]) head1++;              //递减队列的指针如果同步于当前指针需要更新             if(Front==down[head2]) head2++;             //当前指针更新             Front++;         }         ans+=i-Front+1;    }    printf("%lld\n",ans);}int main(){    scanf("%lld",&t);    while(t--){        scanf("%lld%lld",&n,&k);        for(int i=1;i<=n;i++)            scanf("%lld",&data[i]);        slove();    }    return 0;}


                       
0 0
原创粉丝点击