HDU 5289
2016-07-20 20:28
246 查看
Assignment
[b]Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 3478 Accepted Submission(s): 1605
[/b]
[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
[align=left]Recommend[/align]
We have carefully selected several similar problems for you: 5733 5732 5731 5730 5729
算出有多少个区间。满足最大值-最小值 < k
解法:
枚举每个位置x是区间的最左边位置。二分查找,最右的位置r,满足[x,r]的最大值-最小值恰好 < k
r-x+1就是解
用树状数组更新最大最小值,二分位置。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include <cmath>
using namespace std;
#define maxn 100007
int tree1[maxn];
int tree2[maxn];
int lowbit(int i)
{
return i&(-i);
}
void add1(int i,int ans)
{
while(i<maxn)
{
tree1[i]=max(tree1[i],ans);
i+=lowbit(i);
}
}
void add2(int i,int ans)
{
while(i<maxn)
{
tree2[i]=min(tree2[i],ans);
i+=lowbit(i);
}
}
int add3(int i)
{
int res=1000000007;
while(i>0)
{
res=min(tree2[i],res);
i-=lowbit(i);
}
return res;
}
int add4(int i)
{
int res=0;
while(i>0)
{
res=max(tree1[i],res);
i-=lowbit(i);
}
return res;
}
int main()
{
int t,k,n;
cin>>t;
int a[maxn];
while(t--)
{
cin>>n>>k;
memset(tree1,0,sizeof(tree1));
memset(tree2,0x7f7f7f,sizeof(tree2));
for(int j=1; j<=n; j++)
cin>>a[j];
long long ans=0;
for(int j=n; j>=1; j--)
{
add1(j,a[j]);
add2(j,a[j]);
int low=j;
int high=n;
while(low<=high)
{
int mid=(low+high)/2;
int max1=add4(mid);
int min1=add3(mid);
if(max1-min1<k)
low=mid+1;
else
high=mid-1;
}
ans+=low-j;
}
cout<<ans<<endl;
}
return 0;
}
相关文章推荐
- 递归
- 算法基础篇:常见图论最短路算法(Bellman-Ford→SPFA→Dijkstra Floyd-Warshall )入门以及代码解析
- 巩固基础篇:经典二分查找模型及其应用
- 浅谈变换(证明)→反演→莫比乌斯反演→线筛运用
- 中国剩余定理的解析及记忆(扩展欧几里得算法的运用)
- 素数表的快速建立,合数分解,1-2^31内某个长度小于10w的区间素数筛选的三个模板及解析
- 线段树3种基础模型的理解和记忆(任意区间求和,任意区间的所有数加上相同数(懒操作),任意区间所有数变成同一个值再求和)
- ZOJ 1610 Count the Colors 多次更新一次查询,只需要一一标记
- POJ 3264 Balanced Lineup 查询区间最大最小值 基础线状树水题
- HDU 1698 Just a Hook 线状树经典模型之区间变动bool标记,上下同时更新
- POJ 3468 A Simple Problem with Integers(线状树经典模型之lazy操作)
- POJ 2251 Dungeon Master 比较有趣的三维迷宫bfs搜索路径
- 论Acmer的自我修养 (算法学习目标和推荐题目)
- HDU 1260 Tickets (很简单的基础DP题,找到状态转移方程就直接AC了)
- HDU 1176 免费馅饼 (类似于数塔DP的题目,注意边界条件,细节处理)
- HDU 1114 Piggy-Bank (完全背包水题,但注意一下时间输出)
- HDU 1087 Super Jumping!Jumping!Jumping求连续上升子序列的最大和值 (解析)
- HDU 1069 Monkey and Banana 对比优先权的设置和排序问题(解析)
- HDU 1029 Ignatius and the Princess IV(动规水题,有个很精妙的快解法)
- HDU 1024 Max Sum Plus Plus求前n个数中的若干个数分为连续的m段的最大和值(解析)