题意:给T足数据,然后每组一个n和k,表示n个数,k表示最大同意的能力差,接下来n个数表示n个人的能力,求能力差在k之内的区间有几个



分析:维护一个区间的最大值和最小值,使得他们的差小于k,于是採用单调队列



普通单调队列做法:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 1e6+5;
int a[maxn];
struct node{
int index;
int v;
}qd[maxn];
node qx[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int st1,st2,ed1,ed2;
st1=st2=ed1=ed2=1;
long long sum=0;
int j=1;
for(int i=1;i<=n&&j<=n;i++){
if(i==1){
qd[1].index=qx[1].index=1;
qd[1].v=qx[1].v=a[1];
}
else{
while(st1<=ed1){ //单调队列维护最大值
if(qd[ed1].v<=a[i]) ed1--; //比a[i]小的并且下标比i小的出队列
else break;
}
qd[++ed1].v=a[i]; //a[i]入队列
qd[ed1].index=i;
while(st2<=ed2){ //单调队列维护最小值
if(qx[ed2].v>=a[i]) ed2--; //比a[i]大并且下标比i小的出队列
else break;
}
qx[++ed2].v=a[i]; //a[i]入队列
qx[ed2].index=i;
while(qd[st1].v-qx[st2].v>=k&&st1<=ed1&&st2<=ed2) //计数
{
if(qd[st1].index==j) st1++;
if(qx[st2].index==j) st2++;
sum+=(i-j);
j++;
}
}
}
while(j<=n) {
sum+=(n-j+1);
j++;
}
printf("%I64d\n",sum);
}
}

二分单调队列做法:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 1e6+5;
int a[maxn];
struct node{
int index;
int v;
}qd[maxn];
node qx[maxn];
int maxc(int l,int r,int d){ //二分找出d入队列的为止
while(l<=r){
int mid=(l+r)/2;
if(qd[mid].v==d) return mid;
else if(qd[mid].v>d) l=mid+1;
else r=mid-1;
}
return l;
}
int minc(int l,int r,int d){ //二分找出d入队列的为止
while(l<=r){
int mid=(l+r)/2;
if(qx[mid].v==d) return mid;
else if(qx[mid].v<d) l=mid+1;
else r=mid-1;
}
return l;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int st1,st2,ed1,ed2;
st1=st2=ed1=ed2=1;
long long sum=0;
int j=1;
for(int i=1;i<=n&&j<=n;i++){
if(i==1){
qd[1].index=1;
qd[1].v=a[1];
qx[1].index=1;
qx[1].v=a[1];
}
else{
ed1=maxc(st1,ed1,a[i]); //二分找出d入队列的为止,维护最大值
qd[ed1].v=a[i];
qd[ed1].index=i;
ed2=minc(st2,ed2,a[i]); //二分找出d入队列的为止,维护最小值
qx[ed2].v=a[i];
qx[ed2].index=i;
while(qd[st1].v-qx[st2].v>=k&&st1<=ed1&&st2<=ed2)//计数
{
if(qd[st1].index==j) st1++;
if(qx[st2].index==j) st2++;
sum+=(i-j);
j++;
}
}
}
while(j<=n) {
sum+=(n-j+1);
j++;
}
printf("%I64d\n",sum);
}
}



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

  1. HDOJ 5289 Assignment 单调队列

    维护一个递增的和递减的单调队列 Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  2. HDU 5289 Assignment [优先队列 贪心]

    HDU 5289 - Assignment http://acm.hdu.edu.cn/showproblem.php?pid=5289 Tom owns a company and he is th ...

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

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 Problem Description Tom owns a company and he is ...

  4. HDU - 5289 Assignment (RMQ+二分)(单调队列)

    题目链接: Assignment  题意: 给出一个数列,问其中存在多少连续子序列,使得子序列的最大值-最小值<k. 题解: RMQ先处理出每个区间的最大值和最小值(复杂度为:n×logn),相 ...

  5. ACM学习历程—HDU 5289 Assignment(线段树 || RMQ || 单调队列)

    Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered fro ...

  6. HDU 3401 Trade(单调队列优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 题意:炒股.第i天买入一股的价钱api,卖出一股的价钱bpi,最多买入asi股,最多卖出bsi股 ...

  7. Hdu 3410 【单调队列】.cpp

    题意: 给出一个数组,问你对于第i个数,从最后一个比它大的数到它之间比它小的数中最大的那个数的下标,以及它右边到第一个比它大的数中比它小的数中最大的那一个数的下标<下标从1开始>. eg: ...

  8. HDU 5289 Assignment(二分+RMQ-ST)

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

  9. HDU 5749 Colmerauer 单调队列+暴力贡献

    BestCoder Round #84   1003 分析:(先奉上zimpha巨官方题解) 感悟:看到题解单调队列,秒懂如何处理每个点的范围,但是题解的一句算贡献让我纠结半天 已知一个点的up,do ...

随机推荐

  1. Objective-C中的一些特殊的数据类型

    nil nil和C语言的NULL相同,在objc/objc.h中定义.nil表示一个Objctive-C对象,这个对象的指针指向空(没有东西就是空). Nil  首字母大写的Nil和nil有一点不一样 ...

  2. [POJ 1005] I Think I Need a Houseboat C++解题

        I Think I Need a Houseboat Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 81874   ...

  3. spark作业

    假定用户有某个周末网民网购停留时间的日志文本,基于某些业务要求,要求开发 Spark应用程序实现如下功能: 1.实时统计连续网购时间超过半个小时的女性网民信息. 2.周末两天的日志文件第一列为姓名,第 ...

  4. jquery拼接字符串

    1. $("#div").append("<table><tr align='center'>" +"<td >& ...

  5. NOJ——1672剪绳子(博弈)

    [1672] 剪绳子 时间限制: 500 ms 内存限制: 65535 K 问题描述 已知长度为n的线圈,两人依次截取1~m的长度,n, m为整数,不能取者为输. 输入 输入n, m:( 0 < ...

  6. spring分布式事务控制

    应用场景问题描述解决方法多数据源配置单元测试第一种方法:最大努力一次提交模式第二种方法:最大努力一次提交模式 但使用ChainedTransactionManagerChainedTransactio ...

  7. 关于vue属性绑定的问题

    <el-submenu index="></el-submenu> 类似于这样的形式,这里的index是以string的数据格式存在的. <el-submenu ...

  8. 【Vijos1222】等值拉面(DP)

    题意:有N个数对(a[i],b[i]) 每次可以把(x,y)变成(x+a[i],y+b[i])或(x+b[i],x+a[i]),后者称为交换一次 求使abs(x-y)最小时的最小交换次数 n<= ...

  9. Solr5.2.1+Zookeeper3.4.9分布式集群搭建

    1.选取三台服务器 由于机器比较少,现将zookeeper和solr都部署在以下三台机器上.(以下操作都是在172.16.20.101主节点上进行的哦) 172.16.20.101 主节点 172.1 ...

  10. 一款手机端的日历插件ICalendar.js

    我的网盘:http://pan.baidu.com/s/1jIib2Ay