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 from1 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 that1 ≤ x ≤ n the maximum strength among all groups of sizex.
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.
Print n integers in one line. For each x from 1 to n, print the maximum strength among all groups of size x.
10 1 2 3 4 5 4 3 2 1 6
6 4 4 3 3 2 2 1 1 1
题意:对于长度为x的子序列,每个序列的score为这个序列中的最小值,输出长度为x 的子序列的最大值
思路:首先按照值排序,按照从小到大的顺序添加到set中,对于新添加的数,如果他在set中的两边的位置分别为l,r的话,那么他可以修改长度小于r-l-1的子序列的score,使它们变大,线段树维护长度为x的子序列的score的最大值
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=200010;
int N;
struct node
{
int x,id;
bool operator<(const node &a)const
{
return x<a.x;
}
}a[maxn];
set<int> mp;
set<int>::iterator it;
int ans[maxn];
struct IntervalTree
{
int maxv[maxn<<2];
int setv[maxn<<2];
void build(int o,int l,int r)
{
maxv[o]=setv[o]=0;
if(l==r)return ;
int mid=(l+r)>>1;
build(o<<1,l,mid);
build(o<<1,mid+1,r);
}
void update(int o,int l,int r,int q1,int q2,int x)
{
if(q1<=l&&r<=q2)
{
setv[o]=x;
maxv[o]=x;
return ;
}
pushdown(o);
int mid=(l+r)>>1;
if(q1<=mid)update(o<<1,l,mid,q1,q2,x);
if(q2>mid)update(o<<1|1,mid+1,r,q1,q2,x);
}
void pushdown(int o)
{
if(setv[o])
{
setv[o<<1]=setv[o<<1|1]=setv[o];
maxv[o<<1]=maxv[o<<1|1]=setv[o];
setv[o]=0;
}
}
int query(int o,int l,int r,int x)
{
if(l==r)return maxv[o];
pushdown(o);
int mid=(l+r)>>1;
if(x<=mid)return query(o<<1,l,mid,x);
return query(o<<1|1,mid+1,r,x);
}
}tree;
int main()
{
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
scanf("%d",&a[i].x);
a[i].id=i;
}
sort(a+1,a+1+N);
mp.insert(0);mp.insert(N+1);
int l,r;
tree.build(1,1,N);
for(int i=1;i<=N;i++)
{
it=mp.lower_bound(a[i].id);
r=*it;it--;l=*it;
if(r-l-1>=1)tree.update(1,1,N,1,r-l-1,a[i].x);
mp.insert(a[i].id);
}
for(int i=1;i<=N;i++)
ans[i]=tree.query(1,1,N,i);
for(int i=1;i<=N;i++)
printf("%d ",ans[i]);
printf("\n");
return 0;
}
还可以用更简单的方法(下面的代码转自codeforces):
#include <bits/stdc++.h>
using namespace std;
template <typename T> bool maxup(T &a, const T &b) { return a < b ? (a = b, true) : false; }
template <typename T> bool minup(T &a, const T &b) { return a > b ? (a = b, true) : false; }
const int MAX = 200100;
int n;
int a[MAX], low[MAX], high[MAX], m[MAX];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
stack<int> up;
up.push(0);
for (int i = 1; i <= n; i++) {
while (a[i] <= a[up.top()])
up.pop();
low[i] = up.top();
up.push(i);
}
up = stack<int>();
up.push(n + 1);
for (int i = n; i > 0; i--) {
while (a[i] <= a[up.top()])
up.pop();
high[i] = up.top();
up.push(i);
}
for (int i = 1; i <= n; i++)
maxup(m[high[i] - low[i] - 1], a[i]);
for (int i = n - 1; i >= 1; i--)
maxup(m[i], m[i + 1]);
for (int i = 1; i <= n; i++)
printf("%d ", m[i]);
}