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

Total Submission(s): 2555    Accepted Submission(s): 1200


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]

这题有多种做法,但思路差不多,我的做法是依次枚举左端点或者右端点,然后二分查找所能达到的最右边,然后累加起来。

方法一:用树状数组或者rmq枚举左端点,然后二分查找满足条件的最右端点。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define maxn 100060
#define ll long long
#define inf 2000000000
int a[maxn],b1[maxn],b2[maxn];/*b1最小值,b2最大值*/
int lowbit(int x){
return x&(-x);
}
void update1(int pos,int num)
{
while(pos<=maxn){
b1[pos]=min(b1[pos],num);pos+=lowbit(pos);
}
} int question1(int pos)
{
int num=inf;
while(pos>0){
num=min(b1[pos],num);pos-=lowbit(pos);
}
return num;
} void update2(int pos,int num)
{
while(pos<=maxn){
b2[pos]=max(b2[pos],num);pos+=lowbit(pos);
}
} int question2(int pos)
{
int num=-1;
while(pos>0){
num=max(b2[pos],num);pos-=lowbit(pos);
}
return num;
} int main()
{
int n,m,i,j,T,k,l,mid,r;
ll ans;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++){
b1[i]=inf;b2[i]=-1;
scanf("%d",&a[i]);
}
ans=0;
for(i=n;i>=1;i--){
update1(i,a[i]);
update2(i,a[i]);
l=i;r=n;
while(l<=r){
mid=(l+r)/2;
if(question2(mid)-question1(mid)>=k){
r=mid-1;
}
else l=mid+1;
}
//printf("%d %d %d\n",i,l,r);
if(r>=i)
ans+=(ll)(r-i+1);
/*printf("%lld\n",ans);*/
}
printf("%lld\n",ans);
}
return 0;
}

代码二:维护两个单调队列,分别维护最大值和最小值,依次枚举右端点,然后找到符合条件的左端点。(这个方法速度是最快的,只需243ms,惊!)

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define maxn 100060
#define ll long long
int q1[1111111][2],q2[1111111][2];
int a[maxn];
int main()
{
int n,m,i,j,k,front1,front2,rear1,rear2,l,r,T;
ll ans;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
ans=0; front1=front2=1;rear1=rear2=0;l=1;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
while(front1<=rear1 && q1[rear1][0]>=a[i]){
rear1--;
}
rear1++;q1[rear1][0]=a[i];q1[rear1][1]=i; while(front2<=rear2 && q2[rear2][0]<=a[i]){
rear2--;
}
rear2++;q2[rear2][0]=a[i];q2[rear2][1]=i;
while(front1<=rear1 && front2<=rear2 && q2[front2][0]-q1[front1][0]>=k){
l=min(q2[front2][1],q1[front1][1])+1;
if(q2[front2][1]<q1[front1][1]){
front2++;
}
else if(q2[front2][1]>q1[front1][1]){
front1++;
}
else{
front1++;front2++;
}
}
ans+=i-l+1;
/*printf("%d %d %lld\n",i,l,ans);*/
}
printf("%lld\n",ans); }
return 0;
}

hdu5289 Assignment的更多相关文章

  1. hdu5289 Assignment (区间查询最大值最小值,st算法...)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5289 题意:给定长度为n的序列a和一个整数K,找出最大值和最小值的差值小于K的区间.输出满足条件的区间的个 ...

  2. hdu5289(2015多校1)--Assignment(单调队列)

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

  3. hdu5289 2015多校联合第一场1002 Assignment

    题意:给出一个数列.问当中存在多少连续子区间,当中子区间的(最大值-最小值)<k 思路:设dp[i]为从区间1到i满足题意条件的解.终于解即为dp[n]. 此外 如果对于arr[i] 往左遍历 ...

  4. 【HDU5289】Assignment

    题目大意:给定一个长度为 N 的序列,求序列中最大值和最小值相差小于 K 的连续段的个数. 题解: 最大值和最小值相差不超过 K 是一个在值域角度的限制,应考虑采用平衡树或权值...数据结构进行维护. ...

  5. Atitit GRASP(General Responsibility Assignment Software Patterns),中文名称为“通用职责分配软件模式”

    Atitit GRASP(General Responsibility Assignment Software Patterns),中文名称为"通用职责分配软件模式" 1. GRA ...

  6. user initialization list vs constructor assignment

    [本文连接] http://www.cnblogs.com/hellogiser/p/user_initialization_list.html [分析] 初始化列表和构造函数内的赋值语句有何区别? ...

  7. Swift 提示:Initialization of variable was never used consider replacing with assignment to _ or removing it

    Swift 提示:Initialization of variable was never used consider replacing with assignment to _ or removi ...

  8. 代写assignment

    集英服务社,强于形,慧于心 集英服务社,是一家致力于优质学业设计的服务机构,为大家提供优质原创的学业解决方案.多年来,为海内外学子提供了多份原创优质的学业设计解决方案. 集英服务社,代写essay/a ...

  9. [Top-Down Approach] Assignment 1: WebServer [Python]

    Today I complete Socket Programming Assignment 1 Web Server Here is the code: #!/usr/bin/python2.7 # ...

随机推荐

  1. SDUST数据结构 - chap3 栈和队列

    一.判断题: 二.选择题: 三.编程题: 7-1 一元多项式求导: 输入样例: 3 4 -5 2 6 1 -2 0 输出样例: 12 3 -10 1 6 0 代码: #include<bits/ ...

  2. [Usaco 2012 Feb]Nearby Cows

    题目描述 FJ发现他的牛经常跑到附近的草地去吃草,FJ准备给每个草地种足够的草供这个草地以及附近草地的奶牛来吃.FJ有N个草地(1<=N<=100000),有N-1条双向道路连接这些草地, ...

  3. OLED的波形曲线、进度条、图片显示(STM32 HAL库 模拟SPI通信 5线OLED屏幕)详细篇

    少废话,先上效果图 屏幕显示效果         全家福 一.基础认识及引脚介绍 屏幕参数: 尺寸:0.96英寸 分辨率:128*64 驱动芯片:SSD1306 驱动接口协议:SPI 引脚说明: 二. ...

  4. celery应用

    celery---分布式任务队列 Celery是一个简单,灵活且可靠的分布式系统,可以处理大量消息,同时为操作提供维护该系统所需的工具. Celery是一个基于python开发的模块,可以帮助我们对任 ...

  5. Flutter--Flutter开发环境搭建

    一.前言 Flutter 是 Google推出并开源的移动应用开发框架,主打跨平台.高保真.高性能.开发者可以通过 Dart语言开发 App,一套代码同时运行在 iOS 和 Android平台. Fl ...

  6. IGXE搬砖项目

    主要的赚钱方式和倒爷其实是差不多的,自动检测igxe平台上价格与buff相差8.5%以上的饰品,按照历史价格进行一定的过滤,防止翻车,然后自动购买. 2019年经历了十几次的改进以对抗同行的脚本,到1 ...

  7. (Oracle)数据量统计存储过程

    本过程适用于Oracle数据量统计. create or replace procedure SP_GET_TAB_COUNT as v_tableName HDSD_TJ.Tablename%typ ...

  8. CSS居中的常用方式以及优缺点

    前言 居中是页面开发中经常遇到的问题. 使用合适的.简单的.兼容性好的居中方式是我们页面仔在整个工作生涯中都要面对的问题. text-align:center 来看这个例子,一张图片和文字进行居中.如 ...

  9. 洛谷P6218

    感觉此题是P4317 花神的数论题的变形版 Description 求一段区间内二进制中 \(0\) 的个数不小于 \(1\) 的个数的数的个数 Solution 数位 DP 先考虑状态转移方程式,如 ...

  10. 踹树(Trie 字典树)

    Trie 字典树 ~~ 比 KMP 简单多了,无脑子选手学不会KMP,不会结论题~~ 自己懒得造图了OI WIKI 真棒 字典树大概长这么个亚子 呕吼真棒 就是将读进去的字符串根据当前的字符是什么和所 ...