题面
考虑贪心逐位确定,比如对于第一位,先看看最近的
可不可以移动到当前位置上,可以就移动,否则就看看最近的
可不可以,以此类推
如果最近的
确定为当前位上的字符,那么我们确定后面一位的时候,这个
不能用了,需要看第二近的
,这个需要用模拟链表实现
对于判断这个字符时候能在限制步数下移动到当前位,可以用树状数组维护这个字符前面还剩多少字符
Code:
#include <bits/stdc++.h>
#define maxn 100010
#define int long long
using namespace std;
char s[maxn], ans[maxn];
int m, n, tree[maxn], head[maxn], nxt[maxn];
int lowbit(int x){ return x & -x; }
void add(int x, int y){ for (; x <= n; x += lowbit(x)) tree[x] += y; }
int query(int x){ int s = 0; for (; x; x -= lowbit(x)) s += tree[x]; return s; }
signed main(){
scanf("%lld", &m);
scanf("%s", s + 1);
n = strlen(s + 1);
for (int i = n; i; --i) nxt[i] = head[s[i]], head[s[i]] = i, add(i, 1);
for (int i = 1; i <= n; ++i)
for (char j = 'a'; j <= 'z'; ++j)
if (head[j]){
int x = query(head[j] - 1);
if (x <= m){
m -= x;
add(head[j], -1);
head[j] = nxt[head[j]];
printf("%c", j);
break;
}
}
return 0;
}