题意:给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);
}
}



最新文章

  1. Android 热修复方案Tinker
  2. Xcode调试技巧(断点和重构)
  3. WampServer下如何实现多域名配置(虚拟域名配置)
  4. 开始学习node.js了,第一节,fs文件系统 【fs.rename】重命名文件/文件夹
  5. nhibernate操作sql2008数据库(添加数据失败)
  6. Android-AnimationDrawable(二)
  7. 多校6 1003 HDU5795 A Simple Nim (sg函数)
  8. 教程-(SQL DBE、ADO连接)+(Firebird火鸟+DbExpress)+(VF DBF数据库)+(DB Paradox)
  9. 关于C++ 的eof
  10. ANDROID定义自己的观点——模仿瀑布布局(源代码)
  11. python书籍推荐
  12. MySql下视图的创建
  13. Git学习笔记05-撤销修改
  14. BZOJ3772 精神污染 主席树 dfs序
  15. springboot整合视图层之jsp
  16. OSI七层模型与TCP/IP五层模型(转)
  17. 表数据量影响MySQL索引选择
  18. Confluence 6 自定义你的空间
  19. ResNet 论文研读笔记
  20. js-ES6学习笔记-async函数(3)

热门文章

  1. Linux入门(一)
  2. [转]mysql Access denied for user &#39;root&#39;@&#39;localhost&#39; 问题的解决方法
  3. 0016.Linux基础之常用基本命令讲解
  4. js 页面刷新 每N秒钟刷新一次页面
  5. TransH中的Hinge Loss Function
  6. AtCoder Regular Contest 089
  7. 以前刷过的FFT
  8. solr 创建core
  9. 常用类--Date日期类,SimpleDateFormat日期格式类,Calendar日历类,Math数学工具类,Random随机数类
  10. Welcome-to-Swift-19类型嵌套(Nested Types)