题意:
n个人站成一排,有两个教练1号和2号,他们轮流选人
1号教练先选剩下的人中权值最大的,然后选择他左边的k个,右边的k个(空则不选)
再2号,直到所以人都选完
解析:
用数组模拟双向链表
lef[i],i位置左边第一人位置,righ[i],i位置右边第一人位置
每次选完人后,修改空白区间左右连续情况(链表)
用set来求剩下的最大值
ac:
#include<bits/stdc++.h>
#define MAXN 200005
using namespace std;
int a[MAXN],vis[MAXN];
int lef[MAXN],righ[MAXN];
int ans[MAXN];
set<int,greater<int>> st;
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
st.insert(a[i]);
vis[a[i]]=i;
lef[i]=i-1;
righ[i]=i+1;
}
int x=0,cnt;
while(!st.empty())
{
int v=*st.begin();
ans[vis[v]]=x;
st.erase(v);
int l=lef[vis[v]];
int r=righ[vis[v]];
cnt=0;
while(l>0&&cnt<k)
{
ans[l]=x;
st.erase(a[l]);
l=lef[l];
cnt++;
}
cnt=0;
while(r<=n&&cnt<k)
{
ans[r]=x;
st.erase(a[r]);
r=righ[r];
cnt++;
}
//维护已经删除的区间的两端,两端直接相连
righ[l]=r;
lef[r]=l;
x=1-x;
}
for(int i=1;i<=n;i++)
printf("%d",ans[i]+1);
return 0;
}