您的位置:首页 > 其它

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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: