您的位置:首页 > 其它

2015暑假多校联合---Assignment(优先队列)

2016-08-22 16:27 141 查看
原题链接

[align=left]Problem Description[/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]Input[/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]Output[/align]
For each test,output the number of groups.

[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]Sample Output[/align]

5
28

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

[align=left]Author[/align]
FZUACM

[align=left]Source[/align]
2015 Multi-University Training Contest 1

[align=left]Recommend[/align]
We have carefully selected several similar problems for you: 5867 5866 5865 5864 5863

题意:给了n个数和一个k,求有多少个区间满足区间中的极差小于看k;

思路:用两个优先队列q1、q2分别从小到大排列、从大到小排列(存的是下标),从i:0~n-1循环中,两个优先队列都push(i),这时可以得到当前区间的极差,即a[q2.top()]-a[q1.top()], 若小于k,则sum加上区间长度,区间开始位置注意用len1标记,结束位置即len2=i,那么sum+=len2-len1+1; 如果极差大于等于k,那么就要将区间长度缩短,删除一些优先队列中的数,首先判断:若q1.top()>q2.top() 则表示加入的数太小使该区间不符合要求,故删去区间前面太大的数,即删去q2中的数,先删去最大的数,那么最大的数之间的数也要删去,即t=q2.top() ;
len1=t+1;
while(q2.top()<=t) q2.pop();
如果区间极差任然大于等于k,则继续重复上面操作,继续删除,直到区间符合,sum+=len2-len1+1; 若q1.top()<q2.top() 则和上面类似,删除q1中的太小的数;

代码如下:

#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstdio>
using namespace std;
int a[100005];

struct cmp1
{
bool operator()(const int a1,const int a2)
{
return a[a1]>a[a2];
}
};
struct cmp2
{
bool operator()(const int a1,const int a2)
{
return a[a1]<a[a2];
}
};
priority_queue<int,vector<int>,cmp1>q1;
priority_queue<int,vector<int>,cmp2>q2;

int main()
{
int T;
int n,k;
cin>>T;
while(T--)
{
scanf("%d%d",&n,&k);
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
long long sum=0;
int len1=0,len2=0;
for(int i=0; i<n; i++)
{
q1.push(i);
q2.push(i);
len2=i;
endw:
int maxn=a[q2.top()];
int minn=a[q1.top()];
if(maxn-minn<k) sum+=len2-len1+1;
else
{
if(q2.top()>q1.top())
{
len1=t+1;
int t=q1.top();
while(q1.top()<=t)
q1.pop();
goto endw;
}
else
{
len1=t+1;
int t=q2.top();
while(q2.top()<=t)
q2.pop();
goto endw;
}
}
}
while(!q1.empty())
q1.pop();
while(!q2.empty())
q2.pop();
printf("%lld\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: