rt,赛时想了一个二分+主席树的做法,还没调出来/jk
#include<bits/stdc++.h>
#define mid (l+r>>1)
using namespace std;
const int N=2e5+1;
int pos,val,al,ar;
int tot,root[N];
int n,k,a[N];
struct node {
int l,r,cnt;
}T[N<<5];
void build(int &rt,int l,int r) {
rt=++tot; if (l==r) return;
build(T[rt].l,l,mid),build(T[rt].r,mid+1,r);
}
void update(int &p,int q,int l,int r,int pos) {
p=++tot,T[p]=T[q],T[p].cnt++; if (l==r) return;
if (pos<=mid) update(T[p].l,T[q].l,l,mid,pos);
else update(T[p].r,T[q].r,mid+1,r,pos);
}
int query(int p,int q,int l,int r,int k)
{
if (l==r) return l;
int cnt=T[T[p].l].cnt-T[T[q].l].cnt;
if (k<=cnt) return query(T[p].l,T[q].l,l,mid,k);
else return query(T[p].r,T[q].r,mid+1,r,k-cnt);
}
int main()
{
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++)
scanf("%d",a+i);
int lis=0;
for (int i=1,tail=1;i<=n;i++) {
while (a[tail]<a[tail+1]) tail++;
lis=max(lis,tail-i+1),i=tail,tail++;
}
if (lis>=k) {
for (int i=1;i<=n;i++) printf("%d ",a[i]);
return 0;
}
build(root[0],1,n);
for (int i=1;i<=n;i++) update(root[i],root[i-1],1,n,a[i]);
for (int l=1,r=k;r<=n;l++,r++)
{
int L=l,R=r;
while (L<=R) {
int Mid=(L+R)>>1;
if (query(root[r],root[l-1],1,n,Mid-l+1)==a[Mid]) L=Mid+1;
else R=Mid-1;
}
int t=query(root[r],root[l-1],1,n,L-l+1);
if (pos<L) pos=L,val=t,al=l,ar=r;
else if (pos==L&&t>val) val=t,al=l,ar=r;
}
sort(a+al,a+ar+1);
for (int i=1;i<=n;i++) printf("%d ",a[i]);
return 0;
}