51nod 1275:连续子段的差异 单调队列
2016-02-09 12:51
369 查看
1275 连续子段的差异
题目来源: Codility
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
收藏
关注
给出一个包括N个元素的整数数组A,包括A本身在内,共有 (N+1)*N / 2个非空子段。例如:1 3 2的子段为{1} {3} {2} {1 3} {3 2} {1 3 2}。在这些子段中,如果最大值同最小值的差异不超过K,则认为这是一个合格的子段。给出数组A和K,求有多少符合条件的子段。例如:3 5 7 6 3,K = 2,符合条件的子段包括:{3} {5} {7} {6} {3} {3 5} {5 7} {7 6} {5 7 6},共9个。
Input
Output
Input示例
Output示例
从曹博士那里 http://blog.csdn.net/caopengcs/article/category/1502799 学习了这个单调队列的用法,做的时候一直在思考当一个元素退出了队列的时候,对于队列这个区间的最大值和最小值怎么影响,如何维护这个最大值和最小值。
后来学习到,其实这个应该很明显是维护一个最大值最小值的队列才对,当一个元素退出的时候,只需要将这个元素从队列中移走。然后就是 如果(i,j)这个区间符合条件的话 那么(i+1,j) (i+2,j)...肯定也是符合条件的 所以j可以一直往前走 向前维护一个最大值队列 和一个最小值队列,就可以了。
代码:
题目来源: Codility
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
收藏
关注
给出一个包括N个元素的整数数组A,包括A本身在内,共有 (N+1)*N / 2个非空子段。例如:1 3 2的子段为{1} {3} {2} {1 3} {3 2} {1 3 2}。在这些子段中,如果最大值同最小值的差异不超过K,则认为这是一个合格的子段。给出数组A和K,求有多少符合条件的子段。例如:3 5 7 6 3,K = 2,符合条件的子段包括:{3} {5} {7} {6} {3} {3 5} {5 7} {7 6} {5 7 6},共9个。
Input
第1行:2个数N, K(1 <= N <= 50000, 0 <= K <= 10^9) 第2 - N + 1行:每行1个数,对应数组的元素Ai(0 <= A[i] <= 10^9)
Output
输出符合条件的子段数量。
Input示例
5 2 3 5 7 6 2
Output示例
9
从曹博士那里 http://blog.csdn.net/caopengcs/article/category/1502799 学习了这个单调队列的用法,做的时候一直在思考当一个元素退出了队列的时候,对于队列这个区间的最大值和最小值怎么影响,如何维护这个最大值和最小值。
后来学习到,其实这个应该很明显是维护一个最大值最小值的队列才对,当一个元素退出的时候,只需要将这个元素从队列中移走。然后就是 如果(i,j)这个区间符合条件的话 那么(i+1,j) (i+2,j)...肯定也是符合条件的 所以j可以一直往前走 向前维护一个最大值队列 和一个最小值队列,就可以了。
代码:
#pragma warning(disable:4996) #include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <string> #include <cstdio> #include <cmath> #include <queue> #include <stack> #include <deque> #include <set> #include <map> using namespace std; #define INF 0x3fffffff typedef long long ll; const int mod = 1e9 + 7; const int maxn = 50005; ll n, k; ll A[maxn]; deque<int>Amin, Amax; void solve() { int i, j; scanf("%lld%lld", &n, &k); for (i = 1; i <= n; i++) { scanf("%lld", A + i); } ll ans = 0; for (i = 1, j = 1; i <= n; i++) { while (j <= n) { while (!Amin.empty() && A[Amin.back()] >= A[j]) { Amin.pop_back(); } Amin.push_back(j); while (!Amax.empty() && A[Amax.back()] <= A[j]) { Amax.pop_back(); } Amax.push_back(j); if (A[Amax.front()] - A[Amin.front()] <= k) { j++; } else { break; } } ans += (j - i); if (Amin.front() == i) { Amin.pop_front(); } if (Amax.front() == i) { Amax.pop_front(); } } printf("%lld", ans); } int main() { //freopen("i.txt","r",stdin); //freopen("o.txt","w",stdout); solve(); //system("pause"); return 0; }
相关文章推荐
- 自发行python版本制作(二)编译
- Objc生成搜索引擎查询字符串
- Objc生成搜索引擎查询字符串
- Objc生成搜索引擎查询字符串
- 系统突然断电重启导致rac节点无法启动,crs-4000错误
- 拓薪教育-struts2视频教程-任亮
- 可重入和线程安全
- 拓薪教育-spring视频下载-任亮
- usaco 1.2.5 dualpal
- js 的基础知识变量
- (c语言)NOIp 2006 提高组 4 2^k进制数
- usaco 1.2.4 palsquare
- usaco 1.2.3 namenum
- usaco 1.2.2 transform
- uva 568(数学)
- 拓薪教育-hibernate视频下载-任亮
- cocos2d-x中的CCTableView的相关用法
- usaco 1.2.1 milk2
- 设置jsp默认打开方式
- 拓薪教育-Oracle视频下载-任亮