B

来源:互联网 发布:新浪微博绑定域名 编辑:程序博客网 时间:2024/04/30 04:31

Assignment

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 4187    Accepted Submission(s): 1927


Problem Description
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.
 

Input
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[n](0<=a[i]<=10^9),indicate the i-th staff’s ability.
 

Output
For each test,output the number of groups.
 

Sample Input
24 23 1 2 410 50 3 4 5 2 1 6 7 8 9
 

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

Author
FZUACM
 

Source
2015 Multi-University Training Contest 1



题目大意:给出一个数列,问其中存在多少连续子序列,子序列的最大值-最小值<k
一开始觉得用尺子取法,而尺子取法运用与有序对垒队列。本体题则采用单调队列维护最大值最小值,经行进行尺子取法。


以下为代码:
需要注意结果会超int ,所以比赛一般直接开long long 不然莫名坑。
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<queue>
#define LL int
const int MAX=100005;
LL n,k;
LL a[MAX];
std:: deque<LL>min,max;
int main()
{
 LL T;
 scanf("%d",&T);
 LL i,j;
 while(T--)
 {
  long long  sum=0;
  scanf("%d%d",&n,&k);
  for(i=0;i<n;i++)
  {
   scanf("%d",&a[i]);
  }
  while(!min.empty()) min.pop_back();
  while(!max.empty()) max.pop_back();
  for(i=0,j=0,sum=0;i<n;i++)
  {
   while(!min.empty()&&min.back()>a[i]) min.pop_back();
   min.push_back(a[i]);
   while(!max.empty()&&max.back()<a[i]) max.pop_back();
   max.push_back(a[i]);
   while(!min.empty()&&!max.empty()&&max.front()-min.front()>=k)
   {
    sum+=i-j;   //??
    if(a[j]==min.front()) min.pop_front();
    if(a[j]==max.front()) max.pop_front();
    j++;
   }
  }
  while(j<n)
  {
   sum+=(i-j);
   j++;
  }
  printf("%lld\n",sum);
 }
 return 0;
}
原创粉丝点击