题目
【问题描述】
小明要组织一台晚会,总共准备了 n 个节目。然后晚会的时间有限,他只能最终选择其中的 m 个节目。
这 n 个节目是按照小明设想的顺序给定的,顺序不能改变。
小明发现,观众对于晚会的喜欢程度与前几个节目的好看程度有非常大的关系,他希望选出的第一个节目尽可能好看,在此前提下希望第二个节目尽可能好看,依次类推。
小明给每个节目定义了一个好看值,请你帮助小明选择出 m 个节目,满足他的要求。
【输入格式】
输入的第一行包含两个整数 n, m ,表示节目的数量和要选择的数量。
第二行包含 n 个整数,依次为每个节目的好看值。
【输出格式】
输出一行包含 m 个整数,为选出的节目的好看值。
【样例输入】
5 3
3 1 2 5 4
【样例输出】
3 5 4
【样例说明】
选择了第1, 4, 5个节目。
【评测用例规模与约定】
对于 30% 的评测用例,1 <= n <= 20;
对于 60% 的评测用例,1 <= n <= 100;
对于所有评测用例,1 <= n <= 100000,0 <= 节目的好看值 <= 100000。
坑点:最重要的是红色字体部分,意思就是求出n个树中选m个,相对顺序不变,求字典序最大的;由此第一个数肯定要在区间[1,n-m+1]中选择最大的那个数,因为要保证后面还剩下至少m-1个数才可,以此类推,选第二个数也要遵循这样的原则。这样就要求不定区间的最大值,线段树。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
struct node{
int l,r,maxn;//maxn 表示区间[l,r]最大值的下标
}a[400010];
int ans[100010];
int data_s[100010];
void update(int k){
if(data_s[a[k<<1].maxn]>=data_s[a[k<<1|1].maxn]){//注意比较的对象
a[k].maxn=a[k<<1].maxn;
}
else a[k].maxn=a[k<<1|1].maxn;
}
void build(int k,int l,int r){
a[k].l=l;
a[k].r=r;
if(l==r){
a[k].maxn=l;
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
update(k);
}
int query(int k,int l,int r){
if(a[k].l>=l&&a[k].r<=r){
return a[k].maxn;
}
int maxn=0;
int mid=(a[k].l+a[k].r)>>1;
//最好使用三段式//判断mid 和区间的三个关系
if(mid>=l&&mid<r){// 1
int left=query(k<<1,l,mid);
int right=query(k<<1|1,mid+1,r);
if(data_s[left]>=data_s[right])maxn=left;
else maxn=right;
return maxn;
}
if(mid<l){// 2
return query(k<<1|1,l,r);
}
if(mid>=r)return query(k<<1,l,r);// 3
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>data_s[i];
}
build(1,1,n);
ans[0]=0;
for(int k=1;k<=m;k++){
ans[k]=query(1,ans[k-1]+1,n-(m-k));//每次能访问的区间是[ans[k-1]+1,n-(m-k)];
}
for(int i=1;i<=m;i++){
if(i==m)cout<<data_s[ans[i]]<<endl;
else cout<<data_s[ans[i]]<<" ";
}
system("pause");
return 0;
}
// /\ | / |**、
// / \ | / | \
// / \ |/ | / _____ ____ | /
// /------\ |\ |__/ / \ \ /\ / / \ | /
// / \ | \ | / \ \ / \ / /______\ |/
// / \ | \ | \ / \ / \ / \ |
// / \ | \ | \_____/ \/ \/ \_____ |
/**
* ┏┓ ┏┓
* ┏┛┗━━━━━━━┛┗━━━┓
* ┃ ┃
* ┃ ━ ┃
* ┃ > < ┃
* ┃ ┃
* ┃... ⌒ ... ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ 神兽保佑,代码无bug
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
*/
// warm heart, wagging tail,and a smile just for you!
//
// _ooOoo_
// o8888888o
// 88" . "88
// (| -_- |)
// O\ = /O
// ____/`---'\____
// .' \| |// `.
// / \||| : |||// \
// / _||||| -:- |||||- \
// | | \\ - /// | |
// | \_| ''\---/'' | |
// \ .-\__ `-` ___/-. /
// ___`. .' /--.--\ `. . __
// ."" '< `.___\_<|>_/___.' >'"".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `-. \_ __\ /__ _/ .-` / /
// ======`-.____`-.___\_____/___.-`____.-'======
// `=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//