从n个节目中选m个,且所选节目是按照小明设想的顺序给定的,顺序不能改变。
小明发现,观众对于晚会的喜欢程度与前几个节目的好看程度有非常大的关系,
他希望选出的第一个节目尽可能好看,在此前提下希望第二个节目尽可能好看,依次类推。
1 <= n <= 100000,0 <= 节目的好看值 <= 100000
输入
5 3
3 1 2 5 4
输出:3 5 4
先从[1,n-m+1](p1指向区间起点,p2指向区间末尾)中选一个最大值,且记录下标为p,因为p已经是最好看的了,又因为顺序不能改,下一个界面只能从 [p,p2+1] 中选,看看我构造的这组数据就明白了
输入
5 3
3 4 5 1 2
输出
5 1 2
//虽然第1和第2个界面都比第4、5个界面好看,但因为顺序不难改,所以只能选第4、5个了
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int a[N], mx[N<<1];
void pushUp(int k) {
int l=mx[k<<1], r=mx[k<<1|1];
mx[k]=a[l]>=a[r] ? l : r;
}
void build(int l, int r, int k) {
if (l==r) {
mx[k]=l;
return;
}
int m=l+r>>1;
build(l,m,k<<1);
build(m+1,r,k<<1|1);
pushUp(k);
}
//在[ql,qr]中找最大值下表
int query(int ql, int qr, int l, int r, int k) {
if (ql<=l && r<=qr) {
return mx[k];
}
int m=l+r>>1, pos=-1;
if (m>=ql) pos=query(ql,qr,l,m,k<<1);
if (m<qr) {
if (pos==-1) pos=query(ql,qr,m+1,r,k<<1|1);
else {
int t=query(ql,qr,m+1,r,k<<1|1);
if (a[t]>a[pos]) pos=t;
}
}
return pos;
}
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n,m; cin>>n>>m;
for (int i=1; i<=n; i++) cin>>a[i];
build(1,n,1);
int p1=1, p2=n-m+1; //预留出m个界面
while (p1<p2 && p2<=n) {
int p=query(p1,p2,1,n,1);
printf("%d ", a[p]);
p1=p+1, p2++;
}
//如果p1和p2重合或者p1>p2的话,则证明前面没选够m个
while (p2<=n) printf("%d ", a[p2++]);
return 0;
}