Codeforces548D Mike and Feet 数据结构+单调栈+优先队列
2016-07-21 12:21
363 查看
D - Mike and Feet
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d
& %I64u
SubmitStatus
Description
Mike is the president of country What-The-Fatherland. There are
n bears living in this country besides Mike. All of them are standing in a line and they are numbered from
1 to n from left to right.
i-th bear is exactly
ai feet high.
A group of bears is a non-empty contiguous segment of the line. The
size of a group is the number of bears in that group. The
strength of a group is the minimum height of the bear in that group.
Mike is a curious to know for each x such that
1 ≤ x ≤ n the maximum strength among all groups of size
x.
Input
The first line of input contains integer n (1 ≤ n ≤ 2 × 105), the number of bears.
The second line contains n integers separated by space,
a1, a2, ..., an (1 ≤ ai ≤ 109),
heights of bears.
Output
Print n integers in one line. For each
x from 1 to
n, print the maximum strength among all groups of size
x.
Sample Input
Input
Output
解题思路:
仔细的想了好久,发现这题就是一个单调栈问题,正好前段时间正好做过。
1,对于每个数要找他的影响范围,那么就是这个数左边第一个比他小的数,和右边第一个比他小的数字之间。
2,那么问题来了怎么找每一个数的这个区间呢,单调栈可以解决这个问题,参考我的博客
http://blog.csdn.net/fans_ac/article/details/51965804
还算详细的介绍了单调栈的问题,那么这个区间就很好的获取了。
3,获取区间了,怎么求得对于每一个1~k的区间的最大值呢。优先队列可以很好的解决这个问题。
4,优先队列每次都抛出一个最大值,这个最大值的区间就是这个区间的最大值,后面来的都没有大。
5,弹完队列里面所有的数据,就可以找到所有的结果了。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
const int maxn = 200005 ;
struct node{
int val;
int pos ;
};
struct node2{
int len ;
int val ;
bool operator < (const node2 & p)const{
return val<p.val ;
}
} ;
stack<node> qq ;
int arry[maxn] ;
int L[maxn] ;
int R[maxn] ;
priority_queue<node2> pp ;
int main(){
int n ;
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++){
scanf("%d",&arry[i]);
}
while(!qq.empty())qq.pop();
node def;
def.pos = 0 ;
def.val = -0x3f3f3f3f ;
//printf("eys");
qq.push(def);
for(int i = 1;i<=n;i++){
//printf("i = %d\n",i);
while(qq.top().val>=arry[i]){
qq.pop();
}
//printf("s\n");
node t ;
t.val = arry[i] ;
t.pos = i ;
L[i] = qq.top().pos+1;
qq.push(t);
}
//printf("eys");
while(!qq.empty())qq.pop();
def.pos = n+1 ;
def.val = -0x3f3f3f3f ;
qq.push(def);
for(int i = n;i>=1;i--){
while(qq.top().val>=arry[i]){
qq.pop();
}
node t ;
t.val = arry[i] ;
t.pos = i ;
R[i] = qq.top().pos-1;
qq.push(t);
}
// for(int i =1;i<=n;i++){
// printf("%d %d\n",L[i],R[i]);
// }
while(!pp.empty())pp.pop();
for(int i = 1;i<=n;i++){
node2 newnode ;
newnode.len = R[i] - L[i] + 1 ;
newnode.val = arry[i] ;
pp.push(newnode) ;
}
int ans[maxn];
memset(ans,0,sizeof(ans));
while(!pp.empty()){
for(int i=pp.top().len;i>=1;i--){
if(ans[i]!=0)break ;
else ans[i]=pp.top().val ;
}
pp.pop();
}
printf("%d",ans[1]);
for(int i = 2;i<=n;i++){
printf(" %d",ans[i]);
}printf("\n");
}
return 0;
}
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d
& %I64u
SubmitStatus
Description
Mike is the president of country What-The-Fatherland. There are
n bears living in this country besides Mike. All of them are standing in a line and they are numbered from
1 to n from left to right.
i-th bear is exactly
ai feet high.
A group of bears is a non-empty contiguous segment of the line. The
size of a group is the number of bears in that group. The
strength of a group is the minimum height of the bear in that group.
Mike is a curious to know for each x such that
1 ≤ x ≤ n the maximum strength among all groups of size
x.
Input
The first line of input contains integer n (1 ≤ n ≤ 2 × 105), the number of bears.
The second line contains n integers separated by space,
a1, a2, ..., an (1 ≤ ai ≤ 109),
heights of bears.
Output
Print n integers in one line. For each
x from 1 to
n, print the maximum strength among all groups of size
x.
Sample Input
Input
10 1 2 3 4 5 4 3 2 1 6
Output
6 4 4 3 3 2 2 1 1 4000 1
解题思路:
仔细的想了好久,发现这题就是一个单调栈问题,正好前段时间正好做过。
1,对于每个数要找他的影响范围,那么就是这个数左边第一个比他小的数,和右边第一个比他小的数字之间。
2,那么问题来了怎么找每一个数的这个区间呢,单调栈可以解决这个问题,参考我的博客
http://blog.csdn.net/fans_ac/article/details/51965804
还算详细的介绍了单调栈的问题,那么这个区间就很好的获取了。
3,获取区间了,怎么求得对于每一个1~k的区间的最大值呢。优先队列可以很好的解决这个问题。
4,优先队列每次都抛出一个最大值,这个最大值的区间就是这个区间的最大值,后面来的都没有大。
5,弹完队列里面所有的数据,就可以找到所有的结果了。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
const int maxn = 200005 ;
struct node{
int val;
int pos ;
};
struct node2{
int len ;
int val ;
bool operator < (const node2 & p)const{
return val<p.val ;
}
} ;
stack<node> qq ;
int arry[maxn] ;
int L[maxn] ;
int R[maxn] ;
priority_queue<node2> pp ;
int main(){
int n ;
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++){
scanf("%d",&arry[i]);
}
while(!qq.empty())qq.pop();
node def;
def.pos = 0 ;
def.val = -0x3f3f3f3f ;
//printf("eys");
qq.push(def);
for(int i = 1;i<=n;i++){
//printf("i = %d\n",i);
while(qq.top().val>=arry[i]){
qq.pop();
}
//printf("s\n");
node t ;
t.val = arry[i] ;
t.pos = i ;
L[i] = qq.top().pos+1;
qq.push(t);
}
//printf("eys");
while(!qq.empty())qq.pop();
def.pos = n+1 ;
def.val = -0x3f3f3f3f ;
qq.push(def);
for(int i = n;i>=1;i--){
while(qq.top().val>=arry[i]){
qq.pop();
}
node t ;
t.val = arry[i] ;
t.pos = i ;
R[i] = qq.top().pos-1;
qq.push(t);
}
// for(int i =1;i<=n;i++){
// printf("%d %d\n",L[i],R[i]);
// }
while(!pp.empty())pp.pop();
for(int i = 1;i<=n;i++){
node2 newnode ;
newnode.len = R[i] - L[i] + 1 ;
newnode.val = arry[i] ;
pp.push(newnode) ;
}
int ans[maxn];
memset(ans,0,sizeof(ans));
while(!pp.empty()){
for(int i=pp.top().len;i>=1;i--){
if(ans[i]!=0)break ;
else ans[i]=pp.top().val ;
}
pp.pop();
}
printf("%d",ans[1]);
for(int i = 2;i<=n;i++){
printf(" %d",ans[i]);
}printf("\n");
}
return 0;
}
相关文章推荐
- CF620C - Pearls in a Row 数据结构map映射
- HDU 5233 Gunner II 数据结构map+vector
- 数据结构---------二叉搜索树
- 1.16 从大到小顺序返回x,y和z的值
- java实现栈的数据结构
- 数据结构之选择排序<select_sort>
- STL之set集合容器
- hdu 5497 Inversion(树状数组)
- 数据结构与算法分析(三) —— AVL树的实现
- SDUT 1479 数据结构实验之栈:行编辑器
- 数组中最大和的子数组
- 面试金典之数据结构(1)
- 【学习笔记】Redis(1)-数据结构
- opencv学习(4)部分基本数据结构的介绍
- 七种排序的实现
- 冒泡排序的优化方法
- 数据结构 线性双向链表
- 数据结构理论知识
- 数据结构·字符串的最小表示法
- 4-9 二叉树的遍历 (25分)