hdu 5289 Assignment
2015-07-22 20:46
381 查看
Assignment
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1317 Accepted Submission(s): 642
[align=left]Problem Description[/align]
[align=left][/align]
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.
[align=left] [/align]
[align=left]Input[/align]
[align=left][/align]
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
(0<=a[i]<=10^9),indicate the i-th staff’s ability.
[align=left] [/align]
[align=left]Output[/align]
[align=left][/align]
[align=left]For each test,output the number of groups.[/align]
[align=left] [/align]
[align=left]Sample Input[/align]
2 4 2 3 1 2 4 10 5 0 3 4 5 2 1 6 7 8 9
[align=left] [/align]
[align=left]Sample Output[/align]
5 28 HintFirst Sample, the satisfied groups include:[1,1]、[2,2]、[3,3]、[4,4] 、[2,3]
题意:
给一组数 ,要你在这组数中找区间内最大和最小值差不超过k的区间个数和。
分析:
由于数据过大,所以不能太暴力
首先,我们一个数一个数的加进来更新我们当前区间的最大最小值;
当最大最小不符合要求时,那么此时区间一定会缩小;
更新这个小区间;
这样一来,只需要扫一遍这个数列即可。
使用两个单调队列保存每次的最大最小值,值得注意的是我们每次更新区间左端点时一定会向最大最小值的下标更新,因为此时之间的所有值一定是不符合要求的(想想为什么)
#include<cstring> #include<cstdio> #include<algorithm> #include<iostream> using namespace std; int a[1000006]; int que1[1000006]; int que2[1000006]; int main() { int T; scanf("%d",&T); while(T--) { int n,k; scanf("%d%d",&n,&k); int head1=0,head2=0; int tail1=-1,tail2=-1; int vim=0; long long ans=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); while(tail1>=head1&&a[que1[tail1]]<a[i]) tail1--; que1[++tail1]=i; while(tail2>=head2&&a[que2[tail2]]>a[i]) tail2--; que2[++tail2]=i; while(a[que1[head1]]-a[que2[head2]]>=k) { if(que1[head1]>que2[head2]) { vim=que2[head2]; head2++; } else { vim=que1[head1]; head1++; } } ans+=i-vim; } printf("%lld\n",ans); } }
相关文章推荐
- java数组--04
- 封装http请求返回统一json格式数据的网络操作
- [翻译] M13ProgressSuite
- 火星人弃疗声明
- xmapp+netbeans调试
- linux文件压缩与解压
- Masonry介绍与使用实践:快速上手Autolayout
- 南阳oj NYoj 寻找最大数(三) 题目1057
- Android底层代码中用到的几种设计模式
- PAT 1001. A+B Format(水题)
- Poj 3177 Redundant Paths (双连通分支+节点统计)
- fragment-实例创建跟使用
- c语言归并排序(poj2299)《学习记录》
- 开门人和关门人
- break label和continue label
- 暑假- 动态规划 I-(T - Dividing)
- 数据库之视图、索引
- CAVLC中的前缀和后缀
- scrapy模拟登录微博
- Android 属性系统 Property service 设定分析