您的位置:首页 > 其它

hdoj.5289 Assignment【单调队列】 2015/07/25

2015-07-25 11:33 302 查看

Assignment

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 1735 Accepted Submission(s): 835

[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
HintFirst 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

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>

using namespace std;

#define maxn 100000+10

int max_que[maxn],min_que[maxn],num[maxn];
int n,k,t;

int main(){
cin>>t;
int i,ret;
while(t--){
cin>>n>>k;
__int64 ans = 0;
for( i = 1 ; i <= n ; ++i )
cin>>num[i];
int f1,f2,r1,r2,l1,l2;
f1 = f2 = r1 = r2 = 1;
l1 = l2 = 0;
for( i = 1 ; i <= n ; ++i ){
while( f1 < r1 && num[min_que[r1-1]] > num[i] )
r1--;
min_que[r1++] = i;
while( f2 < r2 && num[max_que[r2-1]] < num[i] )
r2--;
max_que[r2++] = i;
while( num[max_que[f2]] - num[min_que[f1]] >= k ){ //why?
if( max_que[f2] < min_que[f1] ){
l2 = max_que[f2++];
}
else{
l1 = min_que[f1++];
}
}
ret = l1>l2?l1:l2;
ans += i - ret;
}
cout<<ans<<endl;
}
return 0;
}
注:单调队列。。。。。。完全没用过也没听说过╮(╯▽╰)╭ 百度了一下才算懂了点,可是这个求组合的方程式还是不怎么理解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: