51nod 1275 连续子段的差异

分析:

1、首先是尺取,尺取到每一个区间,区间满足这个条件,最大-最小<=k;

2、对于一个动态区间,怎么维护他的最大值,最小值(的下标);——单调队列;

  什么时候删掉头结点呢? 当我找到了当前区间的上限;我需要尺取移动头结点了;此时,单调队列不用怕,只要这个头不影响我的单调队列,我就可以不用管;否则弹掉;

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 const int maxn = 50000 + 5;
 6 int a[maxn];
 7
 8
 9 int main()
10 {
11     int n,k;
12     scanf("%d%d",&n,&k);
13     for(int i=0;i<n;i++)
14         scanf("%d",&a[i]);
15
16     int ans = 0;
17     deque<int> Amin,Amax;   //单调递减队列,单调递增队列
18
19     for(int i=0,j=0;i<n;i++) {
20
21         while(j<n) {
22
23             while(!Amin.empty()&&a[j]>=a[Amin.back()])
24                 Amin.pop_back();
25
26             while(!Amax.empty()&&a[j]<=a[Amax.back()])
27                 Amax.pop_back();
28             Amin.push_back(j);
29             Amax.push_back(j);
30
31             if(a[Amin.front()]-a[Amax.front()]<=k)
32                 j++;
33             else break;
34         }
35         ans+=(j-i);
36
37         if(Amin.front()==i)
38             Amin.pop_front();
39         if(Amax.front()==i)
40             Amax.pop_front();
41
42     }
43     printf("%d\n",ans);
44
45     return 0;
46 }

时间: 2024-12-26 20:49:35

51nod 1275 连续子段的差异的相关文章

[2016-05-09][51nod][1049 最大子段和]

时间:2016-05-09 19:04:34 星期一 题目编号:[2016-05-09][51nod][1049 最大子段和] 题目大意: N个整数组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的连续子段和的最大值.当所给的整数均为负数时和为0. 分析: 动态规划 dp[i]=max(dp[i?1]+a[i],a[i])dp[i]=max(dp[i?1]+a[i],a[i]) ans=max(dp[i])ans=max(dp[i]) 全部为负

最大连续子段和的两种线性算法

问题描述:给一个数组a1,a2,...,an.求这个数组的最大连续子段和.(非空子段) 即,定义Sij=ai+...+aj,则题目要求的是 max{Sij}(1<=i<=j<=n) N^3枚举和优化之后的N^2枚举就不说了,还有NlogN的二分算法也不提,想了解的可以看我的另一篇博客:http://www.cnblogs.com/itlqs/p/5097504.html 这里主要详解两种O(n)的算法. 方法一:动态规划 dp[i]表示以第i位为结尾的最大子段和.那么转移方程就是:dp[

SPOJ 1043 Can you answer these queries I 求任意区间最大连续子段和 线段树

题目链接:点击打开链接 维护区间左起连续的最大和,右起连续的和.. #include <cstdio> #include <iostream> #include <algorithm> #include <string.h> #include <math.h> #include <vector> #include <map> using namespace std; #define N 50050 #define Lson

HDOJ-1003 Max Sum(最大连续子段 动态规划)

http://acm.hdu.edu.cn/showproblem.php?pid=1003 给出一个包含n个数字的序列{a1,a2,..,ai,..,an},-1000<=ai<=1000 求最大连续子段和及其起始位置和终止位置,很基础的动态规划(DP)问题,看完DP第一次做的DP题目 DP真的是一种很优美的算法,或者说思想,但是比较难理解,我对DP的理解还很浅薄 # include <stdio.h> # define INF 1000000000 int main() { i

51nod 1049 最大子段和

1049 最大子段和 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 N个整数组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的连续子段和的最大值.当所给的整数均为负数时和为0. 例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13.和为20. Input 第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N + 1行:N个整数(-10^9 <= A

【bzoj5089】最大连续子段和 分块+单调栈

题目描述 给出一个长度为 n 的序列,要求支持如下两种操作: A  l  r  x :将 [l,r] 区间内的所有数加上 x : Q  l  r : 询问 [l,r] 区间的最大连续子段和. 其中,一个区间的最大连续子段和指的是:该区间所有子区间的区间和中的最大值(本题中子区间包括空区间,区间和为 0 ). 输入 第一行两个整数 n.m,表示序列的长度以及操作的数目. 之后的 m 行,每行输入一个操作,含义如题目所述.保证操作为  A  l  r  x  或  Q  l  r  之一. 对于 3

[题解](线段树最大连续子段和)POJ_3667_Hotel

题意:1.求一个最靠左的长x的区间全部为0,并修改为1,输出这个区间的左端点 2.修改一个区间为0 实际上是维护最大连续子段和,原来也写过 大概需要维护一个左/右最大子段和,当前这段最大子段长,再维护一个lazytag #include<iostream> #include<cstdio> #include<cstring> #define mid (l+r>>1) #define ls x<<1 #define rs x<<1|1

bzoj5089 最大连续子段和 分块+复杂度分析+凸包

题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5089 题解 本来打算迟一点再写这个题解的,还有一个小问题没有弄清楚. 不过先写一下存个档吧. 如果只是单点修改,我们的常见做法是维护 \(ls, rs, s\) 表示前缀和最大值,后缀和最大值,区间最大子段和,然后进行区间合并,线段树维护. 但是这个在这里显然是行不通的,因为我们不是单点修改,我们需要考虑一个加标记对于整个连续段的影响. 对于一个长度为 \(k\) 的子段,初始的时候它的和为

51nod 1254 最大子段和 V2

N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为0. 例如:{-2,11,-4,13,-5,-2, 4}将 -4 和 4 交换,{-2,11,4,13,-5,-2, -4},最大子段和为11 + 4 + 13 = 28. 收起 输入 第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N + 1行:N个整数(-10^9 <