首先可以对于每个字母开一个vector[ch],将字符串中每个字符为的字符的下标存入vector[ch].
然后就可以考虑同一个vector[ch]中的顺序关系。
不妨设下标分别为 和 ,其中 , 。
设经过改变后的字符串分别为和,即分别表示将放到第一个和放到第一个后的字符串。
对于,,对于,。
所以只需要考虑。
此时只需要依次比较:
和,和,…,和。
由于,此时,.
所以只需要比较:
和,和,…,和。
也就是说,只需要找到从开始最长的连续相等的子串,比较它和下一个字符的大小即可。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define int long long
#define endl '\n'
void Prework() {
}
void Solve() {
int n, k;cin >> n >> k;
string s;cin >> s;s = ' ' + s;
vector<vector<int>> c(26);
for (int i = 1;i <= n;i++) {
c[s[i] - 'a'].push_back(i);
}
int p = 0;
while (c[p].size() < k) k -= c[p++].size();
vector<int> dp(n + 1);dp[n] = 1;
for (int i = n - 1;i >= 1;i--) {
if (s[i] == s[i + 1]) dp[i] = dp[i + 1] + 1;
else dp[i] = 1;
}
sort(c[p].begin(), c[p].end(), [&](auto u, auto v)->ll {
if (u < v) {
int U = u + dp[u] - 1;
if (U >= v) return (u < v);
else {
return s[U] > s[U + 1];
}
}
else {
int V = v + dp[v] - 1;
if (V >= u) return (u < v);
else {
return s[V] < s[V + 1];
}
}
});
//cout << c[p][k - 1] << endl;
int res = c[p][k - 1];
//cout << res << endl;
cout << s[res];
for (int i = 1;i <= n;i++) {
if (i != res) cout << s[i];
}
cout << endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T = 1;
cin >> T;
Prework();
while (T--) Solve();
}