Hdu 5289-Assignment 贪心,ST表

题目: http://acm.hdu.edu.cn/showproblem.php?pid=5289

Assignment

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

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

2
4 2
3 1 2 4
10 5
0 3 4 5 2 1 6 7 8 9

Sample Output

5
28

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

Recommend

We have carefully selected several similar problems for you:  5669 5668 5667 5666 5665

题意:给你一个数列,再给你一个k,问存在多少个连续子序列使得子序列的最大最小值差值 小于 k.

题解:

贪心+ST表

枚举右端点,因为左端点一定是递增或不变的,所以遇到枚举的区间内的最大最小值差值 大于等于 k,就将左端点加1。然后每次统计个数即可。

注意:答案要开long long。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define MAXN 100010
 4 int n,mn[MAXN][17],mx[MAXN][17],a[MAXN];
 5 int read()
 6 {
 7     int s=0,fh=1;char ch=getchar();
 8     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)fh=-1;ch=getchar();}
 9     while(ch>=‘0‘&&ch<=‘9‘){s=s*10+(ch-‘0‘);ch=getchar();}
10     return s*fh;
11 }
12 void ST()
13 {
14     int i,j;
15     for(i=1;i<=n;i++)mn[i][0]=mx[i][0]=a[i];
16     for(j=1;(1<<j)<=n;j++)
17     {
18         for(i=1;i+(1<<j)-1<=n;i++)
19         {
20             mn[i][j]=min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]);
21             mx[i][j]=max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]);
22         }
23     }
24 }
25 int Query(int l,int r)
26 {
27     int j;
28     for(j=0;(1<<j)<=(r-l+1);j++);j--;
29     return max(mx[l][j],mx[r-(1<<j)+1][j])-min(mn[l][j],mn[r-(1<<j)+1][j]);
30 }
31 int main()
32 {
33     int T,k,i,left,right;
34     long long ans;
35     T=read();
36     while(T--)
37     {
38         n=read();k=read();
39         for(i=1;i<=n;i++)a[i]=read();
40         ST();
41         left=1;//左端点(左端点一定是单调递增的)
42         ans=0;
43         for(right=1;right<=n;right++)//枚举右端点
44         {
45             while(Query(left,right)>=k&&left<right)left++;//在枚举右端点的同时,移动左端点.每次改变右端点时,左端点只可能不变或向右移动.
46             ans+=((long long)right-left+1LL);//统计的子串为以右端点为最右端,最左端在 右端点->左端点 之间.
47         }
48         printf("%lld\n",ans);
49     }
50     fclose(stdin);
51     fclose(stdout);
52     return 0;
53 }
时间: 2024-08-01 01:44:26

Hdu 5289-Assignment 贪心,ST表的相关文章

hdu 5289 Assignment 【ST算法】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 题意:求满足最大值减最小值小于k的区间的数目. 枚举左端点,二分右端点,用st算法求区间最值 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include <string> #incl

HDU 5289 Assignment(二分+RMQ-ST)

Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 3813    Accepted Submission(s): 1771 Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered

hdu 5289 Assignment 二分+rmq

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 332    Accepted Submission(s): 169 Problem Description Tom owns a company and he is

HDU 5289 Assignment(多校2015 RMQ 单调(双端)队列)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 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 tas

HDU 5289 Assignment(RMQ 单调(双端)队列)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 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 tas

hdu 5289 Assignment(2015多校第一场第2题)RMQ+二分(或者multiset模拟过程)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 题意:给你n个数和k,求有多少的区间使得区间内部任意两个数的差值小于k,输出符合要求的区间个数 思路:求出区间的最大最小值,只要他们的差值小于k,那么这个区间就符合要求,但是由于n较大,用暴力一定超时,所以就要用别的方法了:而RMQ是可以求区间的最值的,而且预处理的复杂度只有O(nlogn),而查询只是O(1)处理,这样相对来说节约了时间,再根据右端点来二分枚举左端点(其实不用二分好像更快,估

HDU - 5289 Assignment (RMQ+二分)

题目链接: Assignment  题意: 给出一个数列,问其中存在多少连续子序列,使得子序列的最大值-最小值<k. 题解: RMQ先处理出每个区间的最大值和最小值(复杂度为:n×logn),相当于求出了每个区间的最大值-最小值.那么现在我们枚举左端点,二分右端点就可以在n×logn×logn的时间内过. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAX_N = 1e5+9; 4 int vec[MAX_N]

HDU 5289 Assignment(单调队列)

Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 297    Accepted Submission(s): 152 Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered fro

HDU 5289 Assignment(2015多校训练)

题目链接:戳我 题目大意: 公司有 n 个员工,编号为1....n,每个员工有能力 a[i],现将这些员工分为若干组,每组的员工的编号必须相连,且满足每组员工任意两个人能力的差值小于 k,可以一个人一组 问能分成多少组. 样例解释: 2       //两组测试样例 4 2      // 分别代表n, k 3 1 2 4 // 代表每个员工的能力,故可分组为[1,1].[2,2].[3,3].[4,4] .[2,3], 其中为数组的下标,其他均不符合题意,因为相差的值 >= 2 10 5 //