HDU 5289 Assignment(单调队列)
题意:给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(单调队列)的更多相关文章
- HDOJ 5289 Assignment 单调队列
维护一个递增的和递减的单调队列 Assignment Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Ja ...
- HDU 5289 Assignment [优先队列 贪心]
HDU 5289 - Assignment http://acm.hdu.edu.cn/showproblem.php?pid=5289 Tom owns a company and he is th ...
- HDU 5289 Assignment(多校2015 RMQ 单调(双端)队列)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 Problem Description Tom owns a company and he is ...
- HDU - 5289 Assignment (RMQ+二分)(单调队列)
题目链接: Assignment 题意: 给出一个数列,问其中存在多少连续子序列,使得子序列的最大值-最小值<k. 题解: RMQ先处理出每个区间的最大值和最小值(复杂度为:n×logn),相 ...
- ACM学习历程—HDU 5289 Assignment(线段树 || RMQ || 单调队列)
Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered fro ...
- HDU 3401 Trade(单调队列优化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 题意:炒股.第i天买入一股的价钱api,卖出一股的价钱bpi,最多买入asi股,最多卖出bsi股 ...
- Hdu 3410 【单调队列】.cpp
题意: 给出一个数组,问你对于第i个数,从最后一个比它大的数到它之间比它小的数中最大的那个数的下标,以及它右边到第一个比它大的数中比它小的数中最大的那一个数的下标<下标从1开始>. eg: ...
- HDU 5289 Assignment(二分+RMQ-ST)
Assignment Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total ...
- HDU 5749 Colmerauer 单调队列+暴力贡献
BestCoder Round #84 1003 分析:(先奉上zimpha巨官方题解) 感悟:看到题解单调队列,秒懂如何处理每个点的范围,但是题解的一句算贡献让我纠结半天 已知一个点的up,do ...
随机推荐
- python学习--python 连接SQLServer数据库(两种方法)
1. python 学习.安装教程参照: http://www.runoob.com/python/python-tutorial.html 2. 集成开发环境 JetBrains PyCharm C ...
- 聊聊、Highcharts 动态数据优化版
好久没来博客园了,最近项目太紧.上一篇写了 <Highcharts 之[动态数据]>,不够完善,虽然横纵轴可以动态取数据,但是行业信息是固定的,不能随着大数据热点改变.废话不说,直接上代码 ...
- [git 学习篇] git文件版本回退再学习
需求; 准备把readme.txt回退到上一个版本,也就是“add distributed”的那个版本 首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交3 ...
- API生命周期第三阶段:API实施:使用swagger codegen生成可部署工程,择取一个作为mock service
在分享培训了swagger对于API的设计之后,有一些人问我说:你看,现在咱们前端使用web_API做为mock data在进行测试,后端也有mock 测试.然后我们再进行联调,这之中肯定会出现一些偏 ...
- 九度oj 题目1496:数列区间
题目描述: 有一段长度为n(1<=n<=1000000)的数列,数列中的数字从左至右从1到n编号.初始时数列中的数字都是0. 接下来我们会对其进行m(1<=m<=100000) ...
- iOS键盘高度的获取
代码如下: - (void)viewDidLoad { [super viewDidLoad]; //增加监听,当键盘出现或改变时收出消息 [[NSNotificationCenter default ...
- hihoCoder #1343 Stable Members
题目大意$\newcommand{\SD}{\mathrm{SD}}$ 给定一个 $n+1$ 个点的有向无环图,点从 $0$ 开始编号.无重边.自环,且从每个点 $u$ 都能到达 $0$ 号点.如果每 ...
- BZOJ 2806 [Ctsc2012]Cheat ——后缀自动机 单调队列优化DP
先建出广义后缀自动机. 然后跑出文章中每一个位置的最大匹配距离. 然后定义$f[i]$表示匹配到以$i$结尾的串时,最长的匹配距离. 显然可以二分$L$的取值. 然后容易得到$DP$方程 $f[i]= ...
- Python基础教程总结(一)
引言: 一直都听说Python很强大,以前只是浏览了一些博客,发现有点像数学建模时使用的Matlab,就没有深入去了解了.如今Python使用的地方越来越多,最近又在学习机器学习方面的知识,因此想系统 ...
- jquery中object对象循环遍历的方法
一个朋友问对象如何转为数组,当我问他为啥要转得时候,他告诉我,数组可以用js循环遍历,而对象则不可以.其实呢,对象同样可以循环遍历的啊.不用转换也可以循环!说明你对js或者jquery的某些操作不是很 ...