FOJ 2136 取糖果(单调栈)
来源:互联网 发布:mac网页怎么添加收藏 编辑:程序博客网 时间:2024/05/16 12:43
题目链接:Click here~~
题意:
给一个长度为 n 的序列,对于所有的 k ,询问 min{ max{a[i] ~ a[i+k]} }。
解题思路:
对于类似 min{ max{} } 的问题,很容易想到二分,但是二分法好像解决不了这个问题,因为询问是 O(n) 的。
做法是先用 单调栈 可以 O(n) 预处理出每个 a[i] 作为区间最大值能扩展到的最远位置,记为 l[i] 和 r[i]。
然后将所有元素排序,将排序后先出现的元素(即更小的元素)尽可能覆盖更长的区间长度,问题就解决了。
那么,如何预处理出 l[i] 和 r[i] 呢?
回想朴素求 l[i] 的做法,是对于每个值,向前找比它大的第一个元素。
则对于某个元素 a[i],前面比它小的元素都没有意义了,所以可以将它们删除。
这样,维护的就是一个单调栈,复杂度O(n)。
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int N = 1e5 + 5;struct TT{ int num,l,r; bool operator < (const TT& B) const { return num < B.num; }}a[N];int ans[N],s[N],top;int main(){ int T,n; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i].num); top = 0; for(int i=1;i<=n;i++) { while(top && a[s[top]].num <= a[i].num) --top; a[i].l = top ? s[top] + 1 : 1; s[++top] = i; } top = 0; for(int i=n;i>=1;i--) { while(top && a[s[top]].num <= a[i].num) --top; a[i].r = top ? s[top] - 1 : n; s[++top] = i; } sort(a+1,a+1+n); for(int i=1,j=0;i<=n&&j<=n;i++) { int k = a[i].r - a[i].l + 1; while(j < k) ans[++j] = a[i].num; } for(int j=1;j<=n;j++) printf("%d\n",ans[j]); } return 0;}
- FOJ 2136 取糖果(单调栈)
- 【单调栈】fzu 2136取糖果
- FZU 2136 取糖果(线段树)
- FZU 2136 取糖果
- FZU 2136 取糖果
- 猴子向右看,FOJ上某题 单调栈
- FZU 2136 取糖果 (排序+并查集)
- FOJ 题目1894 志愿者选拔 (单调队列)
- 算法思想——单调队列(Foj志愿者问题)
- fzu 2136 取糖果(线段树)
- FZU Problem 2136 取糖果(线段树离散化,区间合并)
- 单调队列经典题目 FOJ 1894
- foj Problem 1894 志愿者选拔---单调队列
- FOJ 1894 志愿者选拔 单调队列
- fzu 11月赛E 2136 取糖果 线段树
- FZU Problem 2136 取糖果 2种做法
- FOJ 2020 组合(组合数取素数摸模板:Lucas)
- FOJ 1914. Funny Positive Sequence 【单调队列优化】
- Install MySQL Workbench in Ubuntu 12.10 or 12.04
- gcc编译器小知识
- 使用Java还是PHP构建网站(原文http://www.coderanch.com/t/569239/java/java/Java-PHP-Building-Websites)
- wpf
- CoolUI第一阶段完成:45万行,留个印记
- FOJ 2136 取糖果(单调栈)
- 子衿的事(82)
- 原生js控制单选框选中后单次单击取消选中
- ios开发(九):multiview
- 最快捷登陆ssh 服务器的方法
- linux Nginx 日志脚本
- RGB
- C# TabContral选项卡中加载显示窗体后 参数传递测试(图文)
- ENGLISH资料收集(32)-零食大汇总