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
528HintFirst 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
- hdu 5289
- HDU 5289
- HDU 5289
- 2015 多校(1) HDU 5288 HDU 5289
- hdu 5289 Assignment
- HDU 5289 Assignment
- hdu 5289 Assignment
- HDU 5289_Assignment
- HDU 5289 Assignment
- hdu 5289 单调队列
- hdu 5289 Assignment
- hdu 5289 单调队列
- HDU 5289 Assignment
- hdu 5289 Assignment(RMQ)
- hdu 5289 Assignment
- HDU 5289 Assignment
- HDU 5289 Assignment
- HDU-5289<two pointers>
- 期望和方差
- [LeetCode] Product of Array Except Self
- 小白学Python(二) 基本文件操作
- Android开发学习笔记之Activity属性设置
- 用VS 2015写C++代码:体验一下变参模板、完美转发和lambda
- hdu 5289
- Controller激活系统详解 — IoC的应用
- 如何实现人生的三大自由
- Android项目文件结构
- PHPMEMCACHE安装
- Redis 安装与简单示例 <第一篇>
- ls命令、myshell程序编写总结
- openstack 管理三十八 - ceph 与 crushmap
- Objective-C Runtime 运行时之一:类与对象