Assignment

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

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
 
Recommend
We have carefully selected several similar problems for you:  5309 5308 5307 5306 5305 
题目描述:
求一段序列中有多少组这样的子区间,子区间满足这样的条件:最大值与最小值之差不超过k,hdu3415的意思为求长度小于等于k的子序列的最大值。
这道题有一个关键的思想是:小区间的最大值与最小值之差一定小于等于包含它的大区间的最大值与最小值之差,也就是说区间的最大值与最小值之差
是单调的,区间越大,差值越大,当然,大区间是覆盖小区间的,

RMQ: 依次回答以i开始的区间中满足最大值与最小值差值不超过k的子区间的个数

单调队列: 依次回答以i结尾的区间中满足最大值与最小值差值不超过k的子区间的个数

所以我们可以用RMQ或者线段树或者树状数组来查询一个子区间的最大值与最小值,然后枚举起点,二分查找满足条件的终点,或者使用线段树来查找

[i,n]这个区间的终点,如果这个区间满足,那么答案就为n,如果不满足,查左节点,如果不满足继续往下查找,如果满足,说明不满足的点在右节点,
查找右节点。
当然也可用单调队列,枚举终点,i从1到n,数组下标从0开始,初始front=1,[front,i]区间由单调队列给出最大值与最小值,这里使用两个
单调队列,如果[front,i]区间内最大值与最小值差值大于等于k,front++,当然如果两个单调队列的头指针如果等于front,也需要++,每次[front,i]区间内
的答案就为i-front+1,front不必要每次重新初始化为0,因为[front,i-1]本来满足条件,说明[k,i](k<front)这个区间内肯定不满足,小区间都不满足了,说明
[k,i](k<front)也肯定不满足。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#define LL long long
#define maxn 110000
using namespace std;
LL k;
int n;
LL a[maxn];
int up[maxn];
int down[maxn];
int Head1,Tail1;
int Head2,Tail2;
int Front;
void solve()
{
LL ans=;
Head1=; Tail1=;
Head2=; Tail2=;
up[Tail1++]=;
down[Tail2++]=;
Front=;
for(int i=;i<n;i++)
{
while(Head1<Tail1 && a[up[Tail1-]]>a[i])
Tail1--;
up[Tail1++]=i; //存入决策,序号
while(Head2<Tail2 && a[down[Tail2-]]<a[i])
Tail2--;
down[Tail2++]=i;
while(a[down[Head2]]-a[up[Head1]]>=k)
{
if(up[Head1]==Front) Head1++; //删掉队首
if(down[Head2]==Front) Head2++;
Front++;
}
ans+=i-Front+;
// printf("%d ",i-Front+1);
}
printf("%lld\n",ans);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%lld",&n,&k);
for(int i=;i<n;i++)
{
scanf("%lld",&a[i]);
}
solve();
}
return ;
}

由于区间越大,差值越大,所以可以枚举起点,二分查找终点的坐标,ans加上(R-i)+1即可。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#define LL long long
#define maxn 110000
#include <cstring>
using namespace std;
LL k;
int n;
LL a[maxn];
LL d[maxn][]; //d数组代表最小值,以i开始,长度为2^j
LL D[maxn][]; //d数组代表最大值
void init()
{
memset(d,,sizeof(d));
}
void RMQ_init()
{
for(int j=; (<<j) <=n ;j++) //枚举长度
{
for(int i=;(i+ (<<j))-<n;i++) //(1<<j)为长度
{
d[i][j]= min(d[i][j-],d[i+ (<<(j-)) ][j-]);
D[i][j]= max(D[i][j-],D[i+ (<<(j-))][j-]);
//printf("%d %d %lld %lld\n",i,j,d[i][j],D[i][j]);
// cout<<endl;
}
}
}
LL q(int L,int R)
{
int k=;
while((<<(k+)) <= (R-L+))
k++;
LL Min=min(d[L][k],d[R-(<<k)+][k]);
LL Max=max(D[L][k],D[R-(<<k)+][k]);
return Max-Min;
}
void solve()
{
LL ans=;
for(int i=;i<n;i++)
{
int L=i,R=n-;
while(L<=R) //最终L为第一个不满足的点,由于退出循环是R>L,所以R为最后一个满足的点
{
int Mid=(L+R)>>;
if(q(i,Mid) < k)
{
L=Mid+;
}
else
R=Mid-;
}
ans+=(R-i)+;
// printf("%d %d %d\n",i,R,(R-i)+1);
}
printf("%lld\n",ans);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%lld",&n,&k);
for(int i=;i<n;i++)
{
scanf("%lld",&a[i]);
d[i][]=a[i];
D[i][]=a[i];
}
RMQ_init();
// printf("%lld %lld %lld %lld\n",d[0][1],D[0][1],q(1,2),q(0,2));
solve();
}
return ;
}

 

 

hdu 5289(单调队列)的更多相关文章

  1. HDU 3507 单调队列 斜率优化

    斜率优化的模板题 给出n个数以及M,你可以将这些数划分成几个区间,每个区间的值是里面数的和的平方+M,问所有区间值总和最小是多少. 如果不考虑平方,那么我们显然可以使用队列维护单调性,优化DP的线性方 ...

  2. hdu 3530 单调队列最值

    /** HDU 3530 单调队列的应用 题意: 给定一段序列,求出最长的一段子序列使得该子序列中最大最小只差x满足m<=x<=k. 解题思路: 建立两个单调队列分别递增和递减维护(头尾删 ...

  3. hdu 3401 单调队列优化DP

    Trade Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status ...

  4. hdu 3415(单调队列) Max Sum of Max-K-sub-sequence

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3415 大意是给出一个有n个数字的环状序列,让你求一个和最大的连续子序列.这个连续子序列的长度小于等于k. ...

  5. hdu 3401 单调队列优化+dp

    http://acm.hdu.edu.cn/showproblem.php?pid=3401 Trade Time Limit: 2000/1000 MS (Java/Others)    Memor ...

  6. hdu 3415 单调队列

    Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  7. HDU 2191 - 单调队列优化多重背包

    题目: 传送门呀传送门~ Problem Description 急!灾区的食物依然短缺! 为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种 ...

  8. HDU 3530 单调队列

    题目大意:给你n个数, 让你问你最长的满足要求的区间有多长,区间要求:MAX - MIN >= m && MAX - MIN <= k 思路:单调队列维护递增和递减,在加入 ...

  9. HDU 4122 单调队列

    转载自:http://blog.csdn.net/lvshubao1314/article/details/46910271 DES :给出n个订单和m是商店的开放时间.然后n行给出n个订单的信息.然 ...

随机推荐

  1. windows下安装使用WGET

    windows下安装WGET   1. 安装wget    www.2cto.com   网址:http://gnuwin32.sourceforge.net/packages/wget.htm 下载 ...

  2. Toad Oracle 本地/远程数据库导入/导出 数据库备份

    1. Toad进入数据库后,选择 Database ==> Export  ===>  Export Utility Wizard ,选择export  user(按用户导出),选择Toa ...

  3. C++内存分配方式(——选自:C++内存管理技术内幕)

    C++内存分配的区: 1.栈:程序运行时分配的,局部变量,以及传入的参数等存储的地方,在程序结束的时候会回收 2.堆:new分配,由delete释放 3.自由存储区:malloc分配 4.全局/静态存 ...

  4. BZOJ——2697: 特技飞行

    http://www.lydsy.com/JudgeOnline/problem.php?id=2697 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: ...

  5. xml建模

    1.建模的由来 就是将指定的xml字符串当作对象来操作 如果说当对一个指定的xml格式字符串完成了建模操作, 好处在于,只需要调用指定的方法就可以完成预定的字符串获取: 2.建模的思路 1.分析需要被 ...

  6. Meteor计时器

    Meteor有提供它自己的setTimeout和setInterval方法.这些方法被用于确保所有全局变量都具有正确的值.它们就像普通 JavaScript 中的setTimeout 和 setInt ...

  7. 【深度探索c++对象模型】Function语义学之成员函数调用方式

    非静态成员函数 c++的设计准则之一就是:非静态成员函数至少和一般的非成员函数有相同的效率.编译器内部已将member函数实体转换为对等的nonmember函数实体. 转化步骤: 1.改写函数原型以安 ...

  8. vim配置为IDE环境(超详细,极力推荐 git)

    https://github.com/yangyangwithgnu/use_vim_as_ide 1. 用法 git clone https://github.com/VundleVim/Vundl ...

  9. CentOS 7下安装Logstash ELK Stack 日志管理系统(下)

    修改防火墙,对外开放tcp/5601 [root@elk elk]# firewall-cmd --permanent --add-port=5601/tcpSuccess[root@elk elk] ...

  10. Angular2.x

    Angular版本 Angular1和Angular4分别是Angular的两个版本,也就是Angular1.x和Angular2.x(除了Angular1以外,其余都属于Angular2.x). 1 ...