6E-差值不超过k的子段个数

给n个数,然后找出最长的一段子序列(不需要连续),使得这段子序列中的最大值与最小值之间的差值不超过k.找出有几个子序列满足,并输出他们的开始位置和结束位置

#include <cstdio>
#include <iostream>
using namespace std;
int n,k,a[100005];
int Max[100005],Min[100005],h1,t1,h2,t2,j;
inline int Get_Max()
{
    return a[Max[h1+1]];
}
inline int Get_Min()
{
    return a[Min[h2+1]];
}
inline void Update()
{
    while (Max[h1+1]<j) h1++;
    while (Min[h2+1]<j) h2++;
}
inline void Push(int x)
{
    while (h1!=t1 && a[x]>=a[Max[t1]]) t1--;
    Max[++t1]=x;
    while (h2!=t2 && a[x]<=a[Min[t2]]) t2--;
    Min[++t2]=x;
}
int ans=1;
int _O_[100005],_cnt=0;
int main()
{
    scanf("%d%d",&n,&k);
    for (int i=1;i<=n;i++) scanf("%d",a+i);
    Push(1);
    _O_[_cnt=1]=1;
    Max[t1=1]=Min[t2=1]=1;
    j=1;
    for (int i=2;i<=n;i++)
    {
        Push(i);
        while (Get_Max()-Get_Min()>k) j++,Update();
        if (i-j+1>ans)
        {
            ans=i-j+1;
            _O_[_cnt=1]=j;
        }
        else if (i-j+1==ans)
        {
            _O_[++_cnt]=j;
        }
    }
    printf("%d %d\n",ans,_cnt);
    for (int i=1;i<=_cnt;i++)
        printf("%d %d\n",_O_[i],_O_[i]+ans-1);
    return 0;
}
时间: 2024-11-14 12:53:00

6E-差值不超过k的子段个数的相关文章

一维差值维护心得

一维差值维护是一种简单的小算法,该算法用一个巧妙地数列机制解决了多次对数列进行数据加减操作的复杂度,这个算法的思维偏向于动态规范.下面我们从一个问题开始入手介绍这个算法: 问题描述: 已知n个数的数列a,有m次操作,每次操作给定l,r,k三个数,使得al到ar内所有数加上k.注意l到r的区间包含al和ar两个数. 输入数据: 第一行n和m,接下来一行有n个数,表示数列a,接下来有m行,每行有三个数l,r,k,详细解释参考问题描述. 输出数据: 1行n个数,表示经过m次操作之后的数组a. 输入样例

n个数分为两组,两组数的个数尽可能相等,差值最小

题目描述:对于有n个数的数组,分为两组,这两组的数的个数尽可能相等(不超过1),同时两组的数之和的差值最小. 这个题目使用类似0-1背包问题,思路:从k个数中选i个数,求所有可能的和,并把这些和放在flag中用true表示.(k,i,flag见代码) 1 public static void main(String[] args){ 2 int[] arr = {1 , 2 , 3 , 5 , 7 , 8 , 9}; 3 int n = 7; 4 int sum = 0; 5 for(int i

查找(哨兵查找、二分查找、差值查找)

#include <iostream> using namespace std; #define N 10 int fib(int n) { if(n == 0) { return 0; } else if(n == 1) { return 1; } else { return (fib(n-1) + fib(n-2)); } } //普通查找: int sequenctial_Search(int *a,int n,int key) { int i; a[0] = key; i = n; w

日期差值

题目描述: 有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天 输入: 有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD 输出: 每组数据输出一行,即日期差值 样例输入: 20110412 20110422 样例输出: 11 来源: 2009年上海交通大学计算机研究生机试真题 #include <iostream> using namespace std; #define ISYEAR(x) x%100 != 0 && x%4

UESTC 250 数位dp(数字相位数之间的差值不小于2)

http://acm.uestc.edu.cn/#/problem/show/250 windy定义了一种windy数. 不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? Input 包含两个整数,A B. 满足 1≤A≤B≤2000000000 . Output Sample input and output Sample Input Sample Output 1 10 9 Source Windy /*

九度1096:日期差值

http://ac.jobdu.com/problem.php?pid=1096 很经典的计算任意两个日期之间的差值. 方法:利用预处理,以空间换时间的方法,计算任意日期与初始日期0年1月1日之间的差值.再讲两差值求差+1即可.本题关键在预处理部分 #include<stdio.h> #define ISYEAR(x) x%100!=0&&x%4==0||x%400==0?1:0 int dayOfMonth[13][2]={     0,0,     31,31,     2

动态集合中两个最接近的数的差值

题目: 思考: 既然是动态集合,那么我们需要用链表来存储数据方便插入和删除.于是我们可以选用二叉链表,也就是红黑树来存储数据,红黑树由于比较平衡,所以可以得到比较好的查询时间.但是我们并不是直接拿红黑树就可以用了,因为基本的红黑树没有MIN_GAP操作,所以需要自己修改和维护原始的红黑树. 如何给红黑树添加MIN_GAP操作呢?我们需要先给红黑树结构中加入MAX,MIN指针.这个操作可以参考最坏时间为O(1)的求最大小值,当然只取了里面部分新增代码.既然新指针已经添加好了,那么我们以原有红黑树插

[LeetCode] Max Sum of Rectangle No Larger Than K 最大矩阵和不超过K

Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix such that its sum is no larger than k. Example: Given matrix = [ [1, 0, 1], [0, -2, 3] ] k = 2 The answer is 2. Because the sum of rectangle [[0, 1], [

Hibernate中HQL的日期差值计算,可计算相差多少秒

最近有个业务需求就是计算订单创建时间离现在超过 4 小时的订单都查找出来! 那么就需要用到日期函数了. 网上找了一下总共的日期函数有一下几个: CURRENT_DATE() 返回数据库当前日期 时间函数 JPAQL HQL CURRENT_DATE() 返回数据库当前日期 CURRENT_TIME() 时间 时间函数 JPAQL HQL CURRENT_TIME() 返回数据库当前时间 SECOND(d) 从日期中提取具体秒 时间函数 HQL SECOND(时间字段) 空的时候返回null MI