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中的太小的数;
代码如下:
[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; }
相关文章推荐
- 2015暑假多校联合---Expression(区间DP)
- 2017多校联合第八场/hdu 6136Death Podracing(优先队列+循环链表)
- 2015多校联合训练第一场Assignment(hdu5289)三种解法
- 2015暑假多校联合---Problem Killer(暴力)
- [RMQ+二分] 2015多校联合第一场 Assignment
- 2015暑假多校联合---Cake(深搜)
- hdu5289 2015多校联合第一场1002 Assignment
- Dynamic CRM 2013学习笔记(九)CrmFetchKit.js介绍:Fetchxml、多表联合查询, 批量更新
- Rescue 3解法:(1.DFS 2. BFS 3.BFS+优先队列模板)
- 玩转SELECT语句(二)之多表联合查询
- hdu 1873 看病要排队(优先队列)
- Individual Reading Assignment
- 51Nod-消灭兔子-(优先队列)
- poj 3253 Fence Repair (优先队列)
- HDU 多校联合 6033 6043
- 划分树(多校联合)hdu3473
- POJ3190 Stall Reservations (贪心+优先队列)
- oracle加入联合主键
- HDU 多校联合 6045
- 偏差/方差、经验风险最小化、联合界、一致收敛