Problem:
Swapping Characters
You are given a string and a number
k
. You are suggested to generate new strings by swapping any adjacent pair of characters in the string up to
k
times. Write a program to report the lexicographically smallest string among them.
Input
The input is given in the following format.
s
k
The first line provides a string
s
. The second line provides the maximum number of swapping operations
k
(0 ≤
k
≤ 10
9
). The string consists solely of lower-case alphabetical letters and has a length between 1 and 2 × 10
5
.
Output
Output the lexicographically smallest string.
Sample Input 1
pckoshien
3
Sample Output 1
ckopshien
Sample Input 2
pckoshien
10
Sample Output 2
cekophsin

Submitted solutions:

code_snippet: // #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG//[]で配列外参照をするとエラーにしてくれる。上下のやつがないとTLEになるので注意 ABC311Eのサンプル4みたいなデバック中のTLEは防げないので注意
// #endif

#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;


template<typename T> using vc = vector<T>;//prioriy_queueに必要なのでここにこれ書いてます
template<typename T> using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
ll INF = 2e18;

// #include <boost/multiprecision/cpp_int.hpp>//インストール的なのをしてないとできないので注意
// namespace multip = boost::multiprecision;
// //using lll = multip::cpp_int;//無制限を使いたいときはこっちを使う
// using lll = multip::int128_t;

using ld = long double;
using bl = bool;
// using mint = modint998244353;
//using mint = modint1000000007;
//using mint = modint;//使うときはコメントアウトを外す
//mint::set_mod(m);//使うときはコメントアウトを外す

template<class T> using pq = priority_queue<T, vc<T>>;//大きい順
template<class T> using pq_g = priority_queue<T, vc<T>, greater<T>>;//小さい順
//-----------------------------------



//-------------2.配列系--------------
using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>; using vvvvl = vv<vvl>;
using vs = vc<string>; using vvs = vv<string>;
using vb = vc<bl>; using vvb = vv<bl>; using vvvb = vv<vb>;
using vld = vc<ld>; using vvld = vv<ld>; using vvvld = vv<vld>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
// using vmint = vc<mint>; using vvmint = vv<mint>; using vvvmint = vv<vmint>;

//配列外参照対策のやつは一番上の行にあります

#define rep(i,n) for(ll i = 0; i < (n); ++i)//↓でrepを使うので書いてます
template<class T>istream& operator>>(istream& i, vc<T>& v) { rep(j, size(v))i >> v[j]; return i; }

using ar2 = array<ll, 2>;

//----------------------------------



//--------3.コード短縮化とか---------
#define rep(i,n) for(ll i = 0; i < (n); ++i)
#define rrep(i,n) for(ll i = 1; i <= (n); ++i)
#define drep(i,n) for(ll i = (n)-1; i >= 0; --i)
#define nfor(i,s,n) for(ll i=s;i<n;i++)//i=s,s+1...n-1 ノーマルfor
#define dfor(i,s,n) for(ll i = (s)-1; i>=n;i--)//s-1スタートでnまで落ちる

#define nall(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()

#define chmax(x,y) x = max(x,y)
#define chmin(x,y) x = min(x,y)

#define pb push_back
#define eb emplace_back
#define em emplace
#define pob pop_back


#define YES cout<<"Yes"<<endl
#define NO cout<<"No"<<endl
#define YN {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}// if(a==b)YN;
#define dame cout<<-1<<endl


#define vc_unique(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define vc_rotate(v) rotate(v.begin(),v.begin()+1,v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(),v.end())

//if (regex_match(s, regex("")))YN;//文字列sの判定を行う。コメントアウトを外して「""」の中に判定する内容を入れる

//-------------------------------




//---------4.グリッド系----------
vl di = { 0,1,0,-1 };//vl di={0,1,1,1,0,-1,-1,-1};
vl dj = { 1,0,-1,0 };//vl dj={1,1,0,-1,-1,-1,0,1};

bool out_grid(ll i, ll j, ll h, ll w) {//trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_kaiten_r(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//時計回りに90°回転
#define vvl_kaiten_l(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_kaiten_r(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//文字列版 時計回りに90°回転
#define vs_kaiten_l(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転


#define vvl_tenti(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][i]=v[i][j];swap(nx,v);}
#define vs_tenti(v) {ll n = size(v); vs nx(n, string(n,'.')); rep(i, n)rep(j, n)nx[j][i] = v[i][j]; swap(nx, v);}

//--------------------------------




//-----------5.数学系--------------
#define yu_qurid(x,y) ((x)*(x)+(y)*(y))//ユークリッド距離 sqrtはしてないなので注意
#define mannhattan(x1,x2,y1,y2) (abs(x1-x2)+abs(y1-y2)) // マンハッタン距離 = |x1-x2|+|y1-y2|

template<class T>T tousa_sum1(T l, T d, T r) {//初項,公差,末項 で総和を求める
    T wide = (r - l) / d + 1;
    return (l + r) * wide / 2;
}
template<class T>T tousa_sum2(T a, T d, T n) {//初項,交差,項数 で総和を求める
    return (a * 2 + d * (n - 1)) * n / 2;
}
ll kousa_kousuu(ll l, ll r, ll d) {//初項,末項,交差 で等差数列の項数を求める
    return (r - l) / d + 1;
}
// mint touhi_sum(mint a, mint r, ll n) {//初項,公比,項数で等比数列の総和を求める
//     if (r == 1) {
//         return a * n;
//     }
//     mint bunsi = a * (r.pow(n) - mint(1));
//     mint bunbo = r - 1;
//     return bunsi / bunbo;
// }

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

//----------------------------------------------




//-----------6.デバックや出力系------------------
void print(ld x) { printf("%.20Lf\n", x); }

void mukou_debug(vvl to, bool yukou) {//GRAPH × GRAPH用の無向グラフを出力する
    ll n = size(to); ll cnt = 0;//辺の本数
    vc<pair<ll, ll>>v; rep(i, n)for (ll t : to[i])  if (i < t || yukou)cnt++, v.eb(i + 1, t + 1);//有向グラフなら全部OK、違うなら無向なのでf<tのみ見る、using Pのやつを別のにしたいときのためにPを使わずにpair<ll,ll>にしてる
    cout << n << ' ' << cnt << endl; for (auto [f, t] : v)cout << f << ' ' << t << endl;
}

#define vc_cout(v){ll n = size(v);rep(i,n)cout<<v[i]<<endl;}//一次元配列を出力する
#define vv_cout(v){ll n = size(v);rep(i,n){rep(j,size(v[i])){cout<<v[i][j]<<' ';}cout<<endl;}}//二次元配列を出力する

/**2025/10/18
 * BIT
 * 残りのスワップ回数以内で交換可能な文字のうち、辞書順最小の文字で、一番左にあるものから先頭に持っていくことを
 * 確定させるイメージ。
 * i番目の文字をすでに確定させた文字列のすぐ次の位置に持ってくるのに必要なスワップ回数は、
 * 元々の文字列でi番目より手前ですでに確定させた文字がx個とするとi-x回。
 * xはBITで文字を一つ確定させた後にそれが元々あった位置に+1することで高速で求まる。
 */

template <typename T>
struct BIT {
    int n;          // 配列の要素数(数列の要素数+1)
    vector<T> bit;  // データの格納先
    BIT(int n_) : n(n_ + 1), bit(n, 0) {}
    void add(int i, T x) {
        i++;
        for (int idx = i; idx < n; idx += (idx & -idx)) {
            bit[idx] += x;
        }
    }
    // 0番目からl－1番目までの累積和
    T sum(int i) {
        T s(0);
        for (int idx = i; idx > 0; idx -= (idx & -idx)) {
            s += bit[idx];
        }
        return s;
    }
    // [l, r)の要素の総和
    T sum(int l, int r){
        T ret_l = sum(l);
        T ret_r = sum(r);
        return ret_r - ret_l;
    }

    // 累積和が x 以上になる最小のインデックスを返す(x >= 0)
    int lower_bound(T x) {
        int idx = 0;
        int k = 1;
        while (k * 2 < n) k *= 2; // 最大の 2^k

        for (; k > 0; k /= 2) {
            if (idx + k < n && bit[idx + k] < x) {
                x -= bit[idx + k];
                idx += k;
            }
        }
        return idx; // 0-indexed int idx = 0;
    }
};
 
int main(){
    string s;
    cin >> s;
    ll k;
    cin >> k;

    vvl pos(26, vl());
    ll n = s.size();
    rep(i, n) pos[s[i] - 'a'].pb(i);
    rep(i, 26) reverse(nall(pos[i]));

    BIT<ll> bit(n);

    string ans = "";
    rep(i, n){
        rep(j, 26){
            if(pos[j].empty()) continue;
            ll l = pos[j].back();

            ll sum = bit.sum(0, l); // l番目の文字より手前ですでに選ばれた文字の個数
            ll need = l - sum;
            if(need <= k){
                k -= need;
                ans.pb((char)('a' + j));
                bit.add(l, 1);
                pos[j].pop_back();
                break;
            }
        }
    }

    cout << ans << endl;

    
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 6952
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ls u<<1
#define rs u<<1|1
const int N=5e5+5;
ll n,k;
string s,ans;
int pos[30][N],cnt[30],idx[30];
bool vis[N];
int a[N],t[N*4],d[N*2];
int lowbit(int x){
	return x&(-x);
}
void pushup(int u){
	t[u]=min(t[ls],t[rs]); 
}
void build(int u,int l,int r){
	if(l==r){
		t[u]=a[l];
		return ;
	}
	int mid=l+r>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(u);
}
void modify(int u,int loc,int l,int r){
	if(l==r){
		t[u]=100;
		return ;
	}
	int mid=l+r>>1;
	if(loc<=mid) modify(ls,loc,l,mid);
	else modify(rs,loc,mid+1,r);
	pushup(u);
}
int query(int u,int L,ll R,int l,int r){
	if(L<=l&&r<=R){
		return t[u];
	}
	int mid=l+r>>1,res=100;
	if(L<=mid) res=min(res,query(ls,L,R,l,mid));
	if(R>mid) res=min(res,query(rs,L,R,mid+1,r));
	return res;
}
void addx(int u,int v){
	while(u<=n){
		d[u]+=v;
		u+=lowbit(u);
	}
}
int askx(int u){
	int res=0;
	while(u){
		res+=d[u];
		u-=lowbit(u);
	}
	return res;
}
bool check(int x,int p){
	return askx(x)-askx(p)<k;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>s;
	cin>>k;
	n=s.size();
	for(int i=0;i<n;i++){
		a[i+1]=s[i]-'a'+1;
	}
	for(int i=1;i<=n;i++){
		pos[a[i]][++cnt[a[i]]]=i;
		idx[a[i]]=1;
	}
	build(1,1,n);
	for(int i=1;i<=n;i++) addx(i,1);
	for(int i=1;i<=n;){
		if(vis[i]){
			i++;
			continue;
		} 
		int l=i,r=n;
		while(l<r){
			int mid=l+r>>1;
			if(check(mid,i)) l=mid+1;
			else r=mid;
		}
		int x=query(1,i+1,r,1,n);
		if(x>=a[i]){
			ans+=char(a[i]+'a'-1);
			vis[i]=1;
			idx[a[i]]++;i++;
			continue;
		}
		int p=pos[x][idx[x]];
		idx[x]++;
		vis[p]=1;
		k-=(askx(p)-askx(i));
		addx(p,-1);
		ans+=char(x+'a'-1);
		modify(1,p,1,n);
	}
	for(int i=1;i<=n;i++){
		if(!vis[i]) ans+=char(a[i]+'a'-1);
	}
	cout<<ans<<'\n';
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 63716
final_rank: 18

code_snippet: // #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG//[]で配列外参照をするとエラーにしてくれる。上下のやつがないとTLEになるので注意 ABC311Eのサンプル4みたいなデバック中のTLEは防げないので注意
// #endif

#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;


template<typename T> using vc = vector<T>;//prioriy_queueに必要なのでここにこれ書いてます
template<typename T> using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
ll INF = 2e18;

// #include <boost/multiprecision/cpp_int.hpp>//インストール的なのをしてないとできないので注意
// namespace multip = boost::multiprecision;
// //using lll = multip::cpp_int;//無制限を使いたいときはこっちを使う
// using lll = multip::int128_t;

using ld = long double;
using bl = bool;
// using mint = modint998244353;
//using mint = modint1000000007;
//using mint = modint;//使うときはコメントアウトを外す
//mint::set_mod(m);//使うときはコメントアウトを外す

template<class T> using pq = priority_queue<T, vc<T>>;//大きい順
template<class T> using pq_g = priority_queue<T, vc<T>, greater<T>>;//小さい順
//-----------------------------------



//-------------2.配列系--------------
using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>; using vvvvl = vv<vvl>;
using vs = vc<string>; using vvs = vv<string>;
using vb = vc<bl>; using vvb = vv<bl>; using vvvb = vv<vb>;
using vld = vc<ld>; using vvld = vv<ld>; using vvvld = vv<vld>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
// using vmint = vc<mint>; using vvmint = vv<mint>; using vvvmint = vv<vmint>;

//配列外参照対策のやつは一番上の行にあります

#define rep(i,n) for(ll i = 0; i < (n); ++i)//↓でrepを使うので書いてます
template<class T>istream& operator>>(istream& i, vc<T>& v) { rep(j, size(v))i >> v[j]; return i; }

using ar2 = array<ll, 2>;

//----------------------------------



//--------3.コード短縮化とか---------
#define rep(i,n) for(ll i = 0; i < (n); ++i)
#define rrep(i,n) for(ll i = 1; i <= (n); ++i)
#define drep(i,n) for(ll i = (n)-1; i >= 0; --i)
#define nfor(i,s,n) for(ll i=s;i<n;i++)//i=s,s+1...n-1 ノーマルfor
#define dfor(i,s,n) for(ll i = (s)-1; i>=n;i--)//s-1スタートでnまで落ちる

#define nall(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()

#define chmax(x,y) x = max(x,y)
#define chmin(x,y) x = min(x,y)

#define pb push_back
#define eb emplace_back
#define em emplace
#define pob pop_back


#define YES cout<<"Yes"<<endl
#define NO cout<<"No"<<endl
#define YN {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}// if(a==b)YN;
#define dame cout<<-1<<endl


#define vc_unique(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define vc_rotate(v) rotate(v.begin(),v.begin()+1,v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(),v.end())

//if (regex_match(s, regex("")))YN;//文字列sの判定を行う。コメントアウトを外して「""」の中に判定する内容を入れる

//-------------------------------




//---------4.グリッド系----------
vl di = { 0,1,0,-1 };//vl di={0,1,1,1,0,-1,-1,-1};
vl dj = { 1,0,-1,0 };//vl dj={1,1,0,-1,-1,-1,0,1};

bool out_grid(ll i, ll j, ll h, ll w) {//trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_kaiten_r(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//時計回りに90°回転
#define vvl_kaiten_l(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_kaiten_r(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//文字列版 時計回りに90°回転
#define vs_kaiten_l(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転


#define vvl_tenti(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][i]=v[i][j];swap(nx,v);}
#define vs_tenti(v) {ll n = size(v); vs nx(n, string(n,'.')); rep(i, n)rep(j, n)nx[j][i] = v[i][j]; swap(nx, v);}

//--------------------------------




//-----------5.数学系--------------
#define yu_qurid(x,y) ((x)*(x)+(y)*(y))//ユークリッド距離 sqrtはしてないなので注意
#define mannhattan(x1,x2,y1,y2) (abs(x1-x2)+abs(y1-y2)) // マンハッタン距離 = |x1-x2|+|y1-y2|

template<class T>T tousa_sum1(T l, T d, T r) {//初項,公差,末項 で総和を求める
    T wide = (r - l) / d + 1;
    return (l + r) * wide / 2;
}
template<class T>T tousa_sum2(T a, T d, T n) {//初項,交差,項数 で総和を求める
    return (a * 2 + d * (n - 1)) * n / 2;
}
ll kousa_kousuu(ll l, ll r, ll d) {//初項,末項,交差 で等差数列の項数を求める
    return (r - l) / d + 1;
}
// mint touhi_sum(mint a, mint r, ll n) {//初項,公比,項数で等比数列の総和を求める
//     if (r == 1) {
//         return a * n;
//     }
//     mint bunsi = a * (r.pow(n) - mint(1));
//     mint bunbo = r - 1;
//     return bunsi / bunbo;
// }

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

//----------------------------------------------




//-----------6.デバックや出力系------------------
void print(ld x) { printf("%.20Lf\n", x); }

void mukou_debug(vvl to, bool yukou) {//GRAPH × GRAPH用の無向グラフを出力する
    ll n = size(to); ll cnt = 0;//辺の本数
    vc<pair<ll, ll>>v; rep(i, n)for (ll t : to[i])  if (i < t || yukou)cnt++, v.eb(i + 1, t + 1);//有向グラフなら全部OK、違うなら無向なのでf<tのみ見る、using Pのやつを別のにしたいときのためにPを使わずにpair<ll,ll>にしてる
    cout << n << ' ' << cnt << endl; for (auto [f, t] : v)cout << f << ' ' << t << endl;
}

#define vc_cout(v){ll n = size(v);rep(i,n)cout<<v[i]<<endl;}//一次元配列を出力する
#define vv_cout(v){ll n = size(v);rep(i,n){rep(j,size(v[i])){cout<<v[i][j]<<' ';}cout<<endl;}}//二次元配列を出力する

/**2025/10/18
 * BIT
 * 残りのスワップ回数以内で交換可能な文字のうち、辞書順最小の文字で、一番左にあるものから先頭に持っていくことを
 * 確定させるイメージ。
 * i番目の文字をすでに確定させた文字列のすぐ次の位置に持ってくるのに必要なスワップ回数は、
 * 元々の文字列でi番目より手前ですでに確定させた文字がx個とするとi-x回。
 * xはBITで文字を一つ確定させた後にそれが元々あった位置に+1することで高速で求まる。
 */

template <typename T>
struct BIT {
    int n;          // 配列の要素数(数列の要素数+1)
    vector<T> bit;  // データの格納先
    BIT(int n_) : n(n_ + 1), bit(n, 0) {}
    void add(int i, T x) {
        i++;
        for (int idx = i; idx < n; idx += (idx & -idx)) {
            bit[idx] += x;
        }
    }
    // 0番目からl－1番目までの累積和
    T sum(int i) {
        T s(0);
        for (int idx = i; idx > 0; idx -= (idx & -idx)) {
            s += bit[idx];
        }
        return s;
    }
    // [l, r)の要素の総和
    T sum(int l, int r){
        T ret_l = sum(l);
        T ret_r = sum(r);
        return ret_r - ret_l;
    }

    // 累積和が x 以上になる最小のインデックスを返す(x >= 0)
    int lower_bound(T x) {
        int idx = 0;
        int k = 1;
        while (k * 2 < n) k *= 2; // 最大の 2^k

        for (; k > 0; k /= 2) {
            if (idx + k < n && bit[idx + k] < x) {
                x -= bit[idx + k];
                idx += k;
            }
        }
        return idx; // 0-indexed int idx = 0;
    }
};
 
int main(){
    string s;
    ll k;
    cin >> s >> k;
    ll n = s.size();
    vc<set<ll>> v(26, set<ll>()); // s上で文字'a'+iの位置の集合
    
    rep(i, n){
        v[s[i] - 'a'].insert(i);
    }

    BIT<ll> bit(n);

    // 先頭から1文字ずつ決定する
    rep(i, n){
        // 辞書順の小さい文字から残り回数以内で先頭人持ってこれる文字を貪欲に選ぶ
        rep(j, 26){
            if(v[j].empty()) continue;
            ll idx = *v[j].begin(); // まだ使用していない'a'+jのうち、一番左にあるものの位置
            ll x = bit.sum(0, idx); // s[idx]より左側ですでに使用した文字の個数
            ll need = idx - x; // s[idx]をすでに確定させた文字列の次の位置に持ってくるのに必要なスワップ回数
            if(need > k) continue; // 操作回数が足りないならスキップ
            k -= need; // 足りた場合
            cout << (char)('a'+j);
            bit.add(idx, 1); // BITにidx文字目を使用したことを記録
            v[j].erase(idx);
            break;
        }
    }

    cout << endl;

    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 14284
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;

int main(){
    string S; cin>>S;
    int K; cin>>K;

    vector<vector<int>> Sid(26);
    vector<int> Scont(26,0);
    for(int i=0;i<S.size();i++) Sid[S[i]-'a'].push_back(i);

    vector<int> bit(S.size()+1,0);
    for(int i=1;i<=S.size();i++) bit[i]=i&-i;

    string ans;
    for(int i=0;i<S.size();i++){
        for(int j=0;j<26;j++){
            if(Scont[j]>=Sid[j].size()) continue;

            int bit_sum=0,idx=Sid[j][Scont[j]];
            while(idx>0){
                bit_sum+=bit[idx];
                idx-=idx&-idx;
            }
            if(bit_sum>K) continue;

            ans.push_back(j+'a');
            K-=bit_sum;
            idx=Sid[j][Scont[j]]+1;
            while(idx<=S.size()){
                bit[idx]--;
                idx+=idx&-idx;
            }
            Scont[j]++;
            break;
        }
    }
    cout<<ans<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 5264
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ld=long double;
#define fi first
#define se second
#define i128 __int128_t
#define all(x) x.begin(),x.end()
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define si(a) (long)(a.size())
template<typename T>bool chmin(T&a,T b){return b<a?(a=b,1):0;}
template<typename T>bool chmax(T&a,T b){return b>a?(a=b,1):0;}
const int INF=1e9+100;
const long INFL=3e18+100;
struct _ {
   _() { cin.tie(0)->sync_with_stdio(0), cout.tie(0); }
} __;

template<class S, S (*op)(S, S), S (*e)()> struct segtree {
    segtree(int n) : segtree(vector<S>(n,e())) {}
    segtree(const vector<S>& v) : n(si(v)) {
        s=__bit_ceil(unsigned(n));
        log = __countr_zero(unsigned(s));
        d=vector<S>(2*s, e());
        rep(i,n) d[s+i]=v[i];
        for(int i=s;--i;) update(i);
    }
    void set(int p, S x){
        d[p+=s]=x;
        for(int i=1;i<=log;i++) update(p>>i);
    }
    S prod(int l, int r) const {
        S sml=e(), smr=e();
        l+=s;r+=s;
        while(l<r){
            if(l&1) sml=op(sml, d[l++]);
            if(r&1) smr=op(d[--r], smr);
            l>>=1,r>>=1;
        }
        return op(sml,smr);
    }
    S all_prod() const {
        return d[1];
    }
    template<typename F> int max_right(int l, F f) const {
        if(l==n) return n;
        l+=s;
        S sm=e();
        do {
            while(~l&1) l>>=1;
            if(!f(op(sm, d[l]))){
                while(l<s){

                    l<<=1;
                    if(f(op(sm, d[l]))) sm=op(sm, d[l++]);
                }
                return l-s;
            }
            sm=op(sm, d[l++]);
        } while((l&-1)!=1);
        return n;
    }
    

private:
    int n,s,log;
    vector<S>d;
    void update(int k){
        d[k]=op(d[k*2], d[k*2+1]);
    }
};

using S=pair<int,int>;
S op(S l, S r){
    return min(l,r);
}
S e(){
    return S{1e9,1e9};
}

int op2(int l, int r){
    return l+r;
}
int e2(){
    return 0;
}

int main(){
    string s;
    int K;
    cin>>s>>K;
    int N=si(s);

    vector<pair<int,int>> A(N);
    rep(i,N) A[i]=make_pair(s[i]-'a', i);

    segtree<S,op,e> seg(A);
    segtree<int,op2,e2> ex(N);
    rep(i,N) ex.set(i, 1);

    string ans;
    rep(i,N){
        int mv=min(K, N-i-1);
        int r=ex.max_right(0,[&](int x){return x<=mv;});
        S ret=seg.prod(0,r+1);
        ex.set(ret.se,0);
        seg.set(ret.se, e());
        ans+='a'+ret.fi;

        K-=ex.prod(0, ret.se);
    }
    cout<<ans<<"\n";

}
accuracy: 1
time_ms: 40
memory_kb: 12232
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,N) for(int i=0;i<(ll)(N);i++)
#define fi first 
#define se second
#define pb push_back
#define all(X) (X).begin(),(X).end()
ll gcd(ll a,ll b){
    if(b==0)return a;
    return gcd(b,a%b);
}

class segtree{
    public:
    int N;
    vector<ll>data;
    vector<ll>lazy;
    void init (int n){
        N = 1;
        while(N<n)N*=2;
        data.assign(N*2-1,0);
        lazy.assign(N*2-1,0);
    }
    void eval(int k){
        if(lazy[k]==0)return;
        data[k]+=lazy[k];
        if(2*k+2<N*2-1){
            lazy[2*k+1]+=lazy[k];
            lazy[2*k+2]+=lazy[k];
        }
        lazy[k]=0;
    }
    void update(int a,int b,ll x,int k=0,int l=0,int r = -1){
        if(r<0)r=N;
        eval(k);
        if(b<=l||r<=a)return;
        if(a<=l&&r<=b){
            lazy[k]+=x;
            eval(k);
            return;
        }
        update(a,b,x,2*k+1,l,(l+r)/2);
        update(a,b,x,2*k+2,(l+r)/2,r);
        data[k]=max(data[2*k+1],data[2*k+2]);
    }
    ll get(int a,int b,int k=0,int l=0,int r = -1){
        if(r<0)r=N;
        eval(k);
        if(b<=l||r<=a)return 0;
        if(a<=l&&r<=b){
            return data[k];
        }
        ll L=get(a,b,k*2+1,l,(l+r)/2),R=get(a,b,k*2+2,(l+r)/2,r);
        return max(L,R);
    }
};

int main(){
    string S;cin>>S;
    int K;cin>>K;
    int N = S.size();
    segtree seg;
    seg.init(N);
    vector<queue<int>>Q(26);
    rep(i,N){
        Q[S[i]-'a'].push(i);
    }
    string ans;
    rep(i,N){
        rep(j,26){
            if(Q[j].empty())continue;
            int v = Q[j].front();
            ll pos = v+seg.get(v,v+1);
            pos -=i;
            if(pos<=K){
                K-=pos;
                seg.update(0,v+1,1);
                ans.pb('a'+j);
                Q[j].pop();
                break;
            }
        }
    }
    cout<<ans<<endl;
}
accuracy: 1
time_ms: 260
memory_kb: 12616
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#include <iomanip>
#include <numbers>
#include <cassert>
#include <numeric>
#ifdef _MSC_VER
#include <intrin.h>
#endif
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pint = pair<int, int>;
using pll = pair<ll, ll>;
template<typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
#define rep(i, n) for(int i = 0; i < (n); ++i)
template<typename T>
bool chmax(T & a, const T & b) { if (a < b) { a = b; return true; } return false; }
template<typename T>
bool chmin(T & a, const T & b) { if (a > b) { a = b; return true; } return false; }
const int inf = 1e9;
const ll linf = 1e18;
const int dy[] = { 0,0,1,-1 }, dx[] = { 1,-1,0,0 };
namespace atcoder {

    namespace internal {

#ifndef _MSC_VER
        template <class T>
        using is_signed_int128 =
            typename std::conditional<std::is_same<T, __int128_t>::value ||
            std::is_same<T, __int128>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using is_unsigned_int128 =
            typename std::conditional<std::is_same<T, __uint128_t>::value ||
            std::is_same<T, unsigned __int128>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using make_unsigned_int128 =
            typename std::conditional<std::is_same<T, __int128_t>::value,
            __uint128_t,
            unsigned __int128>;

        template <class T>
        using is_integral = typename std::conditional<std::is_integral<T>::value ||
            is_signed_int128<T>::value ||
            is_unsigned_int128<T>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using is_signed_int = typename std::conditional<(is_integral<T>::value&&
            std::is_signed<T>::value) ||
            is_signed_int128<T>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using is_unsigned_int =
            typename std::conditional<(is_integral<T>::value&&
                std::is_unsigned<T>::value) ||
            is_unsigned_int128<T>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using to_unsigned = typename std::conditional<
            is_signed_int128<T>::value,
            make_unsigned_int128<T>,
            typename std::conditional<std::is_signed<T>::value,
            std::make_unsigned<T>,
            std::common_type<T>>::type>::type;

#else

        template <class T> using is_integral = typename std::is_integral<T>;

        template <class T>
        using is_signed_int =
            typename std::conditional<is_integral<T>::value&& std::is_signed<T>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using is_unsigned_int =
            typename std::conditional<is_integral<T>::value&&
            std::is_unsigned<T>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using to_unsigned = typename std::conditional<is_signed_int<T>::value,
            std::make_unsigned<T>,
            std::common_type<T>>::type;

#endif

        template <class T>
        using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

        template <class T>
        using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

        template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

    }

}
namespace atcoder {

    template <class T> struct fenwick_tree {
        using U = internal::to_unsigned_t<T>;

    public:
        fenwick_tree() : _n(0) {}
        fenwick_tree(int n) : _n(n), data(n) {}

        void add(int p, T x) {
            assert(0 <= p && p < _n);
            p++;
            while (p <= _n) {
                data[p - 1] += U(x);
                p += p & -p;
            }
        }

        T sum(int l, int r) {
            assert(0 <= l && l <= r && r <= _n);
            return sum(r) - sum(l);
        }

    private:
        int _n;
        std::vector<U> data;

        U sum(int r) {
            U s = 0;
            while (r > 0) {
                s += data[r - 1];
                r -= r & -r;
            }
            return s;
        }
    };

}
using namespace atcoder;
int main() {
    string s; int k; cin >> s >> k;
    vector<set<int>> ary(26);
    fenwick_tree<int> fw(s.size());
    rep(i, s.size()) {
        ary[s[i] - 'a'].insert(i);
        fw.add(i, 1);
    }
    rep(i, s.size()) {
        rep(j, 26) {
            if (ary[j].size() == 0)continue;
            int sum = fw.sum(0, *ary[j].begin());
            if (sum > k)continue;
            k -= sum;
            s[i] = j + 'a';
            break;
        }
        fw.add(*ary[s[i] - 'a'].begin(), -1);
        ary[s[i] - 'a'].erase(ary[s[i] - 'a'].begin());
    }
    cout << s << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 13696
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct SegTree {
	int n, N;
	vector<ll> dat;
	SegTree (int M) {
		int x = 0;
		while ((1<<x) < M) x++;
		n = (1<<x);
		N = 2 * n;
		dat.assign(N, 0);
	}
	void add(int x, ll p) {
		x += n - 1;
		dat[x] += p;
		while (x > 0) {
			x = (x-1)/2;
			dat[x] = dat[(2*x)+1] + dat[(2*x)+2];
		}
	}
	ll dfs(int a, int b, int k, int l, int r) {
		if (b <= l or r <= a) {
			return 0;
		}
		if (a <= l and r <= b) {
			return dat[k];
		}
		ll vl = dfs(a, b, (2*k)+1, l, (l+r)/2);
		ll vr = dfs(a, b, (2*k)+2, (l+r)/2, r);
		return vl+vr;
	}
	ll query(int a, int b) {
		return dfs(a, b, 0, 0, n);
	}
};
int main() {
	string S;cin >> S;
	ll K;cin >> K;
	vector<queue<int>> ID(26);
	int N = S.size();
	SegTree dec(N+2), non(N+2);
	for (int i = 0;i < N;i++) {
		ID[S[i]-'a'].push(i);
		non.add(i, 1);
	}
	ll tens = 0;
	for (int i = 0;i < N;i++) {
		for (int j = 0;j < 26;j++) {
			if (ID[j].empty()) continue;
			int nid = ID[j].front();
			ll newten = tens + non.query(0,nid);
			if (newten <= K) {
				char nc = 'a';nc += j;
				cout << nc;
				dec.add(nid, 1);
				non.add(nid, -1);
				ID[j].pop();
				tens = newten;
				break;
			}
		}
	}
	cout << endl;
}
accuracy: 1
time_ms: 110
memory_kb: 12576
final_rank: 11

code_snippet: #pragma GCC target ("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _USE_MATH_DEFINES
#include<iostream>
#include<string>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<list>
#include<iomanip>
#include<vector>
#include<random>
#include<functional>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<unordered_map>
#include<climits>
#include<fstream>
#include<complex>
#include<time.h>
#include<cassert>
#include<functional>
#include<numeric>
#include<tuple>
using namespace std;
using ll = long long;
using ld = long double;
using H = pair<ll, ll>;
using P = pair<ll, H>;
using vi = vector<ll>;
#define all(a) (a).begin(),(a).end()
#define fs first
#define sc second
#define xx first
#define yy second.first
#define zz second.second
#define Q(i,j,k) mkp(i,mkp(j,k))
#define rng(i,s,n) for(ll i = (s) ; i < (n) ; i++)
#define rep(i,n) rng(i, 0, (n))
#define mkp make_pair
#define vec vector
#define pb emplace_back
#define siz(a) (int)(a).size()
#define crdcomp(b) sort(all((b)));(b).erase(unique(all((b))),(b).end())
#define getidx(b,i) (lower_bound(all(b),(i))-(b).begin())
#define ssp(i,n) (i==(ll)(n)-1?"\n":" ")
#define ctoi(c) (int)(c-'0')
#define itoc(c) (char)(c+'0')
#define cyes printf("Yes\n")
#define cno printf("No\n")
#define cdf(n) for(int quetimes_=(n);quetimes_>0;quetimes_--)
#define gcj printf("Case #%lld: ",qq123_+1)
#define readv(a,n) a.resize(n,0);rep(i,(n)) a[i]=read()
#define found(a,x) (a.find(x)!=a.end())
constexpr ll mod = (ll)1e9 + 7;
constexpr ll Mod = 998244353;
constexpr ld EPS = 1e-10;
constexpr ll inf = (ll)3 * 1e18;
constexpr int Inf = (ll)15 * 1e8;
constexpr int dx[] = { -1,1,0,0 }, dy[] = { 0,0,-1,1 };
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
ll read() { ll u, k = scanf("%lld", &u); return u; }
string reads() { string s; cin >> s; return s; }
H readh(short g = 0) { H u; int k = scanf("%lld %lld", &u.fs, &u.sc); if (g == 1) u.fs--, u.sc--; if (g == 2) u.fs--; return u; }
bool ina(H t, int h, int w) { return 0 <= t.fs && t.fs < h && 0 <= t.sc && t.sc < w; }
bool ina(int t, int l, int r) { return l <= t && t < r; }
ll gcd(ll i, ll j) { return j ? gcd(j, i % j) : i; }
ll popcount(ll x) {
    int sum = 0; for (int i = 0; i < 60; i++)if ((1ll << i) & x) sum++;
    return sum;
}
template<typename T>
class csum {
    vec<T> v;
public:
    csum(vec<T>& a) :v(a) { build(); }
    csum() {}
    void init(vec<T>& a) { v = a; build(); }
    void build() {
        for (int i = 1; i < v.size(); i++) v[i] += v[i - 1];
    }
    //[l,r]
    T a(int l, int r) {
        if (r < l) return 0;
        return v[r] - (l == 0 ? 0 : v[l - 1]);
    }
    //[l,r)
    T b(int l, int r) {
        return a(l, r - 1);
    }
    T a(pair<int, int>t) {
        return a(t.first, t.second);
    }
    T b(pair<int, int>t) {
        return b(t.first, t.second);
    }
};
class mint {
public:ll v;
      mint(ll v = 0) { s(v % mod + mod); }
      constexpr static int mod = (ll)1e9 + 7;
      constexpr static int fn_ = (ll)2e6 + 5;
      static mint fact[fn_], comp[fn_];
      mint pow(int x) const {
          mint b(v), c(1);
          while (x) {
              if (x & 1) c *= b;
              b *= b;
              x >>= 1;
          }
          return c;
      }
      inline mint& s(int vv) {
          v = vv < mod ? vv : vv - mod;
          return *this;
      }
      inline mint inv()const { return pow(mod - 2); }
      inline mint operator-()const { return mint() - *this; }
      inline mint& operator+=(const mint b) { return s(v + b.v); }
      inline mint& operator-=(const mint b) { return s(v + mod - b.v); }
      inline mint& operator*=(const mint b) { v = v * b.v % mod; return *this; }
      inline mint& operator/=(const mint b) { v = v * b.inv().v % mod; return *this; }
      inline mint operator+(const mint b) const { return mint(v) += b; }
      inline mint operator-(const mint b) const { return mint(v) -= b; }
      inline mint operator*(const mint b) const { return mint(v) *= b; }
      inline mint operator/(const mint b) const { return mint(v) /= b; }
      friend ostream& operator<<(ostream& os, const mint& m) {
          return os << m.v;
      }
      friend istream& operator>>(istream& is, mint& m) {
          int x; is >> x; m = mint(x);
          return is;
      }
      bool operator<(const mint& r)const { return v < r.v; }
      bool operator>(const mint& r)const { return v > r.v; }
      bool operator<=(const mint& r)const { return v <= r.v; }
      bool operator>=(const mint& r)const { return v >= r.v; }
      bool operator==(const mint& r)const { return v == r.v; }
      bool operator!=(const mint& r)const { return v != r.v; }
      explicit operator bool()const { return v; }
      explicit operator int()const { return v; }
      mint comb(mint k) {
          if (k > * this) return mint();
          if (!fact[0]) combinit();
          if (v >= fn_) {
              if (k > * this - k) k = *this - k;
              mint tmp(1);
              for (int i = v; i >= v - k.v + 1; i--) tmp *= mint(i);
              return tmp * comp[k.v];
          }
          return fact[v] * comp[k.v] * comp[v - k.v];
      }//nCk
      mint perm(mint k) {
          if (k > * this) return mint();
          if (!fact[0]) combinit();
          if (v >= fn_) {
              mint tmp(1);
              for (int i = v; i >= v - k.v + 1; i--) tmp *= mint(i);
              return tmp;
          }
          return fact[v] * comp[v - k.v];
      }//nPk
      static void combinit() {
          fact[0] = 1;
          for (int i = 1; i < fn_; i++) fact[i] = fact[i - 1] * mint(i);
          comp[fn_ - 1] = fact[fn_ - 1].inv();
          for (int i = fn_ - 2; i >= 0; i--) comp[i] = comp[i + 1] * mint(i + 1);
      }
}; mint mint::fact[fn_], mint::comp[fn_];
//--------------------------------------------------------------

class BIT {
    using ll = long long;
    int size;
    vector<ll>dat;
public:
    BIT() {}
    BIT(int n) { init(n); }
    void init(int n) {
        size = n;
        dat.clear();
        dat.assign(size + 1, 0);
    }
    void add(int i, ll x) {
        if (i <= 0)
            i++;
        while (i <= size) {
            dat[i] += x;
            i += i & -i;
        }
    }//0-indexed
    void add(int l, int r, ll x) {
        add(l, x); add(r, -x);
    }//[l,r)
    ll query(int i) {
        i++;
        ll sum = 0;
        while (i > 0) {
            sum += dat[i];
            i -= i & -i;
        }
        return sum;
    }//0-indexed
    ll query(int l, int r) {
        return query(r - 1) - query(l - 1);
    }//[l,r)
};//size, 0-indexed
//---------------------------------------------------------------------
BIT bit;
signed main() {
    string s; int k;
    cin >> s >> k;
    deque<int>pls[26];
    rep(i, siz(s)) {
        pls[int(s[i] - 'a')].pb(i);
    }
    bit.init(siz(s));
    string ans = "";
    rep(i, siz(s)) {
        rep(j, 26) {
            //もしもjがiに置けるなら
            if (pls[j].empty()) continue;
            int t = pls[j].front();
            if (t - i + bit.query(t) > k) continue;
            pls[j].pop_front();
            k -= t - i + bit.query(t);
            bit.add(0, t + 1, 1);
            ans += char(j + 'a');
            break;
        }
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 37392
final_rank: 15

code_snippet: // #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG//[]で配列外参照をするとエラーにしてくれる。上下のやつがないとTLEになるので注意 ABC311Eのサンプル4みたいなデバック中のTLEは防げないので注意
// #endif

#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;


template<typename T> using vc = vector<T>;//prioriy_queueに必要なのでここにこれ書いてます
template<typename T> using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
ll INF = 2e18;

// #include <boost/multiprecision/cpp_int.hpp>//インストール的なのをしてないとできないので注意
// namespace multip = boost::multiprecision;
// //using lll = multip::cpp_int;//無制限を使いたいときはこっちを使う
// using lll = multip::int128_t;

using ld = long double;
using bl = bool;
// using mint = modint998244353;
//using mint = modint1000000007;
//using mint = modint;//使うときはコメントアウトを外す
//mint::set_mod(m);//使うときはコメントアウトを外す

template<class T> using pq = priority_queue<T, vc<T>>;//大きい順
template<class T> using pq_g = priority_queue<T, vc<T>, greater<T>>;//小さい順
//-----------------------------------



//-------------2.配列系--------------
using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>; using vvvvl = vv<vvl>;
using vs = vc<string>; using vvs = vv<string>;
using vb = vc<bl>; using vvb = vv<bl>; using vvvb = vv<vb>;
using vld = vc<ld>; using vvld = vv<ld>; using vvvld = vv<vld>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
// using vmint = vc<mint>; using vvmint = vv<mint>; using vvvmint = vv<vmint>;

//配列外参照対策のやつは一番上の行にあります

#define rep(i,n) for(ll i = 0; i < (n); ++i)//↓でrepを使うので書いてます
template<class T>istream& operator>>(istream& i, vc<T>& v) { rep(j, size(v))i >> v[j]; return i; }

using ar2 = array<ll, 2>;

//----------------------------------



//--------3.コード短縮化とか---------
#define rep(i,n) for(ll i = 0; i < (n); ++i)
#define rrep(i,n) for(ll i = 1; i <= (n); ++i)
#define drep(i,n) for(ll i = (n)-1; i >= 0; --i)
#define nfor(i,s,n) for(ll i=s;i<n;i++)//i=s,s+1...n-1 ノーマルfor
#define dfor(i,s,n) for(ll i = (s)-1; i>=n;i--)//s-1スタートでnまで落ちる

#define nall(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()

#define chmax(x,y) x = max(x,y)
#define chmin(x,y) x = min(x,y)

#define pb push_back
#define eb emplace_back
#define em emplace
#define pob pop_back


#define YES cout<<"Yes"<<endl
#define NO cout<<"No"<<endl
#define YN {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}// if(a==b)YN;
#define dame cout<<-1<<endl


#define vc_unique(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define vc_rotate(v) rotate(v.begin(),v.begin()+1,v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(),v.end())

//if (regex_match(s, regex("")))YN;//文字列sの判定を行う。コメントアウトを外して「""」の中に判定する内容を入れる

//-------------------------------




//---------4.グリッド系----------
vl di = { 0,1,0,-1 };//vl di={0,1,1,1,0,-1,-1,-1};
vl dj = { 1,0,-1,0 };//vl dj={1,1,0,-1,-1,-1,0,1};

bool out_grid(ll i, ll j, ll h, ll w) {//trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_kaiten_r(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//時計回りに90°回転
#define vvl_kaiten_l(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_kaiten_r(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//文字列版 時計回りに90°回転
#define vs_kaiten_l(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転


#define vvl_tenti(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][i]=v[i][j];swap(nx,v);}
#define vs_tenti(v) {ll n = size(v); vs nx(n, string(n,'.')); rep(i, n)rep(j, n)nx[j][i] = v[i][j]; swap(nx, v);}

//--------------------------------




//-----------5.数学系--------------
#define yu_qurid(x,y) ((x)*(x)+(y)*(y))//ユークリッド距離 sqrtはしてないなので注意
#define mannhattan(x1,x2,y1,y2) (abs(x1-x2)+abs(y1-y2)) // マンハッタン距離 = |x1-x2|+|y1-y2|

template<class T>T tousa_sum1(T l, T d, T r) {//初項,公差,末項 で総和を求める
    T wide = (r - l) / d + 1;
    return (l + r) * wide / 2;
}
template<class T>T tousa_sum2(T a, T d, T n) {//初項,交差,項数 で総和を求める
    return (a * 2 + d * (n - 1)) * n / 2;
}
ll kousa_kousuu(ll l, ll r, ll d) {//初項,末項,交差 で等差数列の項数を求める
    return (r - l) / d + 1;
}
// mint touhi_sum(mint a, mint r, ll n) {//初項,公比,項数で等比数列の総和を求める
//     if (r == 1) {
//         return a * n;
//     }
//     mint bunsi = a * (r.pow(n) - mint(1));
//     mint bunbo = r - 1;
//     return bunsi / bunbo;
// }

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

//----------------------------------------------




//-----------6.デバックや出力系------------------
void print(ld x) { printf("%.20Lf\n", x); }

void mukou_debug(vvl to, bool yukou) {//GRAPH × GRAPH用の無向グラフを出力する
    ll n = size(to); ll cnt = 0;//辺の本数
    vc<pair<ll, ll>>v; rep(i, n)for (ll t : to[i])  if (i < t || yukou)cnt++, v.eb(i + 1, t + 1);//有向グラフなら全部OK、違うなら無向なのでf<tのみ見る、using Pのやつを別のにしたいときのためにPを使わずにpair<ll,ll>にしてる
    cout << n << ' ' << cnt << endl; for (auto [f, t] : v)cout << f << ' ' << t << endl;
}

#define vc_cout(v){ll n = size(v);rep(i,n)cout<<v[i]<<endl;}//一次元配列を出力する
#define vv_cout(v){ll n = size(v);rep(i,n){rep(j,size(v[i])){cout<<v[i][j]<<' ';}cout<<endl;}}//二次元配列を出力する

template <typename T>
struct BIT {
    int n;          // 配列の要素数(数列の要素数+1)
    vector<T> bit;  // データの格納先
    BIT(int n_) : n(n_ + 1), bit(n, 0) {}
    void add(int i, T x) {
        i++;
        for (int idx = i; idx < n; idx += (idx & -idx)) {
            bit[idx] += x;
        }
    }
    // 0番目からl－1番目までの累積和
    T sum(int i) {
        T s(0);
        for (int idx = i; idx > 0; idx -= (idx & -idx)) {
            s += bit[idx];
        }
        return s;
    }
    // [l, r)の要素の総和
    T sum(int l, int r){
        T ret_l = sum(l);
        T ret_r = sum(r);
        return ret_r - ret_l;
    }

    // 累積和が x 以上になる最小のインデックスを返す(x >= 0)
    int lower_bound(T x) {
        int idx = 0;
        int k = 1;
        while (k * 2 < n) k *= 2; // 最大の 2^k

        for (; k > 0; k /= 2) {
            if (idx + k < n && bit[idx + k] < x) {
                x -= bit[idx + k];
                idx += k;
            }
        }
        return idx; // 0-indexed int idx = 0;
    }
};

int main(){
    string s;
    ll k;
    cin >> s >> k;

    vc<deque<ll>> pos(26, deque<ll>());
    rep(i, s.size()){
        pos[s[i] - 'a'].push_back(i);
    }

    BIT<ll> bit(s.size());
    
    rep(j, s.size()){
        rep(i, 26){
            if(pos[i].empty()) continue;
            ll f = pos[i].front();
            ll cnt = f - bit.sum(f);

            if(cnt <= k){
                cout << char('a' + i);

                pos[i].pop_front();
                bit.add(f, 1);
                k -= cnt;
                break;
            }
        }
    }

    cout << endl;

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 6552
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#include <atcoder/all>
using namespace atcoder;

template <typename T>
using vc = vector<T>;
template <typename T>
using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
ll INF = 2e18;

using ld = long double;
using bl = bool;
using mint = modint998244353;
// using mint = modint1000000007;
//   using mint = modint;
//   mint::set_mod(m);

template <class T>
using pq = priority_queue<T, vc<T>>;
template <class T>
using pq_g = priority_queue<T, vc<T>, greater<T>>;
//-----------------------------------

//-------------2.配列系--------------

using pii = pair<int, int>;
using pll = pair<long long, long long>;

#define rep(i, n) for (ll i = 0; i < (n); ++i)
template <class T>
istream &operator>>(istream &i, vc<T> &v)
{
    rep(j, size(v)) i >> v[j];
    return i;
}

using ar2 = array<ll, 2>;

//----------------------------------

//--------3.コード短縮化とか---------
const double PI = 3.141592653589793238;
const int inf = 1073741823;
const ll infl = 1LL << 60;
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string abc = "abcdefghijklmnopqrstuvwxyz";

#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define drep(i, n) for (ll i = (n) - 1; i >= 0; --i)
#define nfor(i, s, n) for (ll i = s; i < n; i++)
#define dfor(i, s, n) for (ll i = (s) - 1; i >= n; i--)

#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)

#define Yes cout << "Yes" << endl
#define No cout << "No" << endl
#define YN                     \
    {                          \
        cout << "Yes" << endl; \
    }                          \
    else                       \
    {                          \
        cout << "No" << endl;  \
    } // if(a==b)YN;

#define vc_unique(v) v.erase(unique(v.begin(), v.end()), v.end());
#define vc_rotate(v) rotate(v.begin(), v.begin() + 1, v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(), v.end())

//-------------------------------

//---------4.グリッド系----------
vector<int> dx = {1, 0, -1, 0}; //  dx={1,1,0,-1,-1,-1,0,1};
vector<int> dy = {0, 1, 0, -1}; //  dy={0,1,1,1,0,-1,-1,-1};

bool out_grid(ll i, ll j, ll h, ll w = -1)
{
    if (w == -1)
    {
        w = h;
    }
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_rotate(v)                                   \
    {                                                   \
        ll n = size(v);                                 \
        vvl nx(n, vl(n));                               \
        rep(i, n) rep(j, n) nx[j][n - i - 1] = v[i][j]; \
        swap(nx, v);                                    \
    } // 時計回りに90°回転
// #define vvl_rotate(v) {ll n = size(v);vvl
// nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_rotate(v)                                    \
    {                                                   \
        ll n = size(v);                                 \
        vs nx(n, string(n, '.'));                       \
        rep(i, n) rep(j, n) nx[j][n - i - 1] = v[i][j]; \
        swap(nx, v);                                    \
    } // 文字列版 時計回りに90°回転
// #define vs_rotate(v) {ll n = size(v);vs
// nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転

#define vvl_transpos(v)                         \
    {                                           \
        ll n = size(v);                         \
        vvl nx(n, vl(n));                       \
        rep(i, n) rep(j, n) nx[j][i] = v[i][j]; \
        swap(nx, v);                            \
    }
#define vs_transpos(v)                          \
    {                                           \
        ll n = size(v);                         \
        vs nx(n, string(n, '.'));               \
        rep(i, n) rep(j, n) nx[j][i] = v[i][j]; \
        swap(nx, v);                            \
    }

//--------------------------------

//-----------5.数学系--------------
#define euclid(x, y) ((x) * (x) + (y) * (y)) // ユークリッド距離 2乗のまま
#define manhattan(x1, x2, y1, y2) \
    (abs(x1 - x2) + abs(y1 - y2)) // マンハッタン距離 = |x1-x2|+|y1-y2|

template <class T>
T tousa_sum1(T l, T d, T r)
{ // 初項,公差,末項 で総和を求める
    T wide = (r - l) / d + 1;
    return (l + r) * wide / 2;
}
template <class T>
T tousa_sum2(T a, T d, T n)
{ // 初項,交差,項数 で総和を求める
    return (a * 2 + d * (n - 1)) * n / 2;
}
ll kousa_kousuu(ll l, ll r, ll d)
{ // 初項,末項,交差 で等差数列の項数を求める
    return (r - l) / d + 1;
}
mint touhi_sum(mint a, mint r,
               ll n)
{ // 初項,公比,項数で等比数列の総和を求める
    if (r == 1)
    {
        return a * n;
    }
    mint bunsi = a * (r.pow(n) - mint(1));
    mint bunbo = r - 1;
    return bunsi / bunbo;
}

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

//----------------------------------------------

//-----------6.デバックや出力系------------------
void print(ld x) { printf("%.20Lf\n", x); }

#define print_vec(v)                   \
    {                                  \
        ll n = size(v);                \
        rep(i, n) cout << v[i] << " "; \
        cout << endl;                  \
    } // 一次元配列を出力する(改行なし)

#define vc_cout(v)                      \
    {                                   \
        ll n = size(v);                 \
        rep(i, n) cout << v[i] << endl; \
    } // 一次元配列を出力する(改行あり)
#define vv_cout(v)                                         \
    {                                                      \
        ll n = size(v);                                    \
        rep(i, n)                                          \
        {                                                  \
            rep(j, size(v[i])) { cout << v[i][j] << ' '; } \
            cout << endl;                                  \
        }                                                  \
    } // 二次元配列を出力する
//----------------------------------------------
// Segment Tree
template <class Monoid>
struct SegmentTree
{
    using Func = function<Monoid(Monoid, Monoid)>;

    // core member
    int N;
    Func OP;
    Monoid IDENTITY;

    // inner data
    int log, offset;
    vector<Monoid> dat;

    // constructor
    SegmentTree() {}
    SegmentTree(int n, const Func &op, const Monoid &identity)
    {
        init(n, op, identity);
    }
    SegmentTree(const vector<Monoid> &v, const Func &op, const Monoid &identity)
    {
        init(v, op, identity);
    }
    void init(int n, const Func &op, const Monoid &identity)
    {
        N = n;
        OP = op;
        IDENTITY = identity;
        log = 0, offset = 1;
        while (offset < N)
            ++log, offset <<= 1;
        dat.assign(offset * 2, IDENTITY);
    }
    void init(const vector<Monoid> &v, const Func &op, const Monoid &identity)
    {
        init((int)v.size(), op, identity);
        build(v);
    }
    void pull(int k)
    {
        dat[k] = OP(dat[k * 2], dat[k * 2 + 1]);
    }
    void build(const vector<Monoid> &v)
    {
        assert(N == (int)v.size());
        for (int i = 0; i < N; ++i)
            dat[i + offset] = v[i];
        for (int k = offset - 1; k > 0; --k)
            pull(k);
    }
    int size() const
    {
        return N;
    }
    Monoid operator[](int i) const
    {
        return dat[i + offset];
    }

    // update A[i], i is 0-indexed, O(log N)
    void set(int i, const Monoid &v)
    {
        assert(0 <= i && i < N);
        int k = i + offset;
        dat[k] = v;
        while (k >>= 1)
            pull(k);
    }

    void add(int i, const Monoid &v)
    {
        assert(0 <= i && i < N);
        int k = i + offset;
        dat[k] += v;
        while (k >>= 1)
            pull(k);
    }

    // get [l, r), l and r are 0-indexed, O(log N)
    Monoid prod(int l, int r)
    {
        assert(0 <= l && l <= r && r <= N);
        Monoid val_left = IDENTITY, val_right = IDENTITY;
        l += offset, r += offset;
        for (; l < r; l >>= 1, r >>= 1)
        {
            if (l & 1)
                val_left = OP(val_left, dat[l++]);
            if (r & 1)
                val_right = OP(dat[--r], val_right);
        }
        return OP(val_left, val_right);
    }
    Monoid all_prod()
    {
        return dat[1];
    }

    // get max r that f(get(l, r)) = True (0-indexed), O(log N)
    // f(IDENTITY) need to be True
    int max_right(const function<bool(Monoid)> f, int l = 0)
    {
        if (l == N)
            return N;
        l += offset;
        Monoid sum = IDENTITY;
        do
        {
            while (l % 2 == 0)
                l >>= 1;
            if (!f(OP(sum, dat[l])))
            {
                while (l < offset)
                {
                    l = l * 2;
                    if (f(OP(sum, dat[l])))
                    {
                        sum = OP(sum, dat[l]);
                        ++l;
                    }
                }
                return l - offset;
            }
            sum = OP(sum, dat[l]);
            ++l;
        } while ((l & -l) != l); // stop if l = 2^e
        return N;
    }

    // get min l that f(get(l, r)) = True (0-indexed), O(log N)
    // f(IDENTITY) need to be True
    int min_left(const function<bool(Monoid)> f, int r = -1)
    {
        if (r == 0)
            return 0;
        if (r == -1)
            r = N;
        r += offset;
        Monoid sum = IDENTITY;
        do
        {
            --r;
            while (r > 1 && (r % 2))
                r >>= 1;
            if (!f(OP(dat[r], sum)))
            {
                while (r < offset)
                {
                    r = r * 2 + 1;
                    if (f(OP(dat[r], sum)))
                    {
                        sum = OP(dat[r], sum);
                        --r;
                    }
                }
                return r + 1 - offset;
            }
            sum = OP(dat[r], sum);
        } while ((r & -r) != r);
        return 0;
    }

    // debug
    friend ostream &operator<<(ostream &s, const SegmentTree &seg)
    {
        for (int i = 0; i < (int)seg.size(); ++i)
        {
            s << seg[i];
            if (i != (int)seg.size() - 1)
                s << " ";
        }
        return s;
    }
};
using S = pair<char, int>;
S e = {'{', inf};
S op(S a, S b)
{
    if (a.first == b.first)
    {
        if (a.second <= b.second)
            return a;
        else
            return b;
    }
    else
    {
        if (a.first < b.first)
            return a;
        else
            return b;
    }
}

using T = int;
T et = 0;
T opt(T a, T b) { return a + b; }
int k;
bool f(int a)
{
    return a <= k + 1;
}
int main()
{
    cout << fixed << setprecision(10);
    string s;
    cin >> s >> k;
    int n = s.size();
    vector<S> a(n);
    rep(i, n) a[i] = {s[i], i};

    vector<T> b(n, 1);
    SegmentTree<S> seg(a, op, e);
    SegmentTree<T> cnt(b, opt, et);

    string ans;
    rep(i, n)
    {
        int idx = cnt.max_right(f);
        auto [c, l] = seg.prod(0, idx);

        ans.push_back(c);
        k -= cnt.prod(0, l);
        seg.set(l, {'{', inf});
        cnt.set(l, 0);
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 12512
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...)
#endif

template <class T>
struct BinaryIndexedTree {
    int N;
    vector<T> data;

    BinaryIndexedTree() = default;
    BinaryIndexedTree(int size) : N(size), data(size + 1, 0) {}
    BinaryIndexedTree(const vector<T>& v) : N(ssize(v)), data(N + 1) {
        for (int i = 1; i <= N; i++) {
            data[i] += v[i - 1];
            int j = i + (i & -i);
            if (j <= N) data[j] += data[i];
        }
    }
    // i 番目に x を加算
    void add(int i, T x) {
        assert(0 <= i && i < N);
        for (++i; i <= N; i += i & -i) data[i] += x;
    }
    // [l, r) に x を加算 (imos 法)
    void imos(int l, int r, T x) { add(l, x), add(r, -x); }
    // [0, i) の和 (imos 法で区間加算して i 番目の値を取るときは sum(i + 1))
    T sum(int i) const {
        if (i < 0) return T{};
        T res{};
        for (; i > 0; i -= i & -i) res += data[i];
        return res;
    }
    // [l, r) の和
    T sum(int l, int r) const { return sum(r) - sum(l); }
    // i 番目の値
    T operator[](int i) const { return sum(i + 1) - sum(i); }
    // [0, i) の和が w 以上となる最小の i
    int lower_bound(T w) const {
        if (w <= 0) return 0;
        int i = 0;
        for (int k = 1 << __lg(N); k > 0; k >>= 1) {
            if (i + k <= N && data[i + k] < w) {
                w -= data[i + k];
                i += k;
            }
        }
        return i + 1;
    }
};

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    string s;
    int k;
    cin >> s >> k;

    int n = s.size();
    vector<queue<int>> pos(26);
    for (int i = 0; i < n; i++) pos[s[i] - 'a'].emplace(i);

    // bit[i] := i 文字目が未使用なら 1, 使用済みなら 0
    BinaryIndexedTree<int> bit(vector<int>(n, 1));

    // 辞書順に決定していく
    string ans = "";
    while (true) {
        bool is_update = false;
        for (int c = 0; c < 26; c++) {
            if (!pos[c].empty()) {
                int i = pos[c].front();
                int cost = bit.sum(i);
                if (cost <= k) {
                    k -= cost;
                    bit.add(i, -1);  // 使用
                    pos[c].pop();
                    ans += (char)('a' + c);
                    is_update = true;
                }
            }
            if (is_update) break;
        }
        if (!is_update) break;
    }

    cout << ans << '\n';
}
accuracy: 1
time_ms: 10
memory_kb: 6016
final_rank: 1

code_snippet: // #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG//[]で配列外参照をするとエラーにしてくれる。上下のやつがないとTLEになるので注意 ABC311Eのサンプル4みたいなデバック中のTLEは防げないので注意
// #endif

#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;


template<typename T> using vc = vector<T>;//prioriy_queueに必要なのでここにこれ書いてます
template<typename T> using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
ll INF = 2e18;

// #include <boost/multiprecision/cpp_int.hpp>//インストール的なのをしてないとできないので注意
// namespace multip = boost::multiprecision;
// //using lll = multip::cpp_int;//無制限を使いたいときはこっちを使う
// using lll = multip::int128_t;

using ld = long double;
using bl = bool;
// using mint = modint998244353;
//using mint = modint1000000007;
//using mint = modint;//使うときはコメントアウトを外す
//mint::set_mod(m);//使うときはコメントアウトを外す

template<class T> using pq = priority_queue<T, vc<T>>;//大きい順
template<class T> using pq_g = priority_queue<T, vc<T>, greater<T>>;//小さい順
//-----------------------------------



//-------------2.配列系--------------
using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>; using vvvvl = vv<vvl>;
using vs = vc<string>; using vvs = vv<string>;
using vb = vc<bl>; using vvb = vv<bl>; using vvvb = vv<vb>;
using vld = vc<ld>; using vvld = vv<ld>; using vvvld = vv<vld>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
// using vmint = vc<mint>; using vvmint = vv<mint>; using vvvmint = vv<vmint>;

//配列外参照対策のやつは一番上の行にあります

#define rep(i,n) for(ll i = 0; i < (n); ++i)//↓でrepを使うので書いてます
template<class T>istream& operator>>(istream& i, vc<T>& v) { rep(j, size(v))i >> v[j]; return i; }

using ar2 = array<ll, 2>;

//----------------------------------



//--------3.コード短縮化とか---------
#define rep(i,n) for(ll i = 0; i < (n); ++i)
#define rrep(i,n) for(ll i = 1; i <= (n); ++i)
#define drep(i,n) for(ll i = (n)-1; i >= 0; --i)
#define nfor(i,s,n) for(ll i=s;i<n;i++)//i=s,s+1...n-1 ノーマルfor
#define dfor(i,s,n) for(ll i = (s)-1; i>=n;i--)//s-1スタートでnまで落ちる

#define nall(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()

#define chmax(x,y) x = max(x,y)
#define chmin(x,y) x = min(x,y)

#define pb push_back
#define eb emplace_back
#define em emplace
#define pob pop_back


#define YES cout<<"Yes"<<endl
#define NO cout<<"No"<<endl
#define YN {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}// if(a==b)YN;
#define dame cout<<-1<<endl


#define vc_unique(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define vc_rotate(v) rotate(v.begin(),v.begin()+1,v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(),v.end())

//if (regex_match(s, regex("")))YN;//文字列sの判定を行う。コメントアウトを外して「""」の中に判定する内容を入れる

//-------------------------------




//---------4.グリッド系----------
vl di = { 0,1,0,-1 };//vl di={0,1,1,1,0,-1,-1,-1};
vl dj = { 1,0,-1,0 };//vl dj={1,1,0,-1,-1,-1,0,1};

bool out_grid(ll i, ll j, ll h, ll w) {//trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_kaiten_r(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//時計回りに90°回転
#define vvl_kaiten_l(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_kaiten_r(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//文字列版 時計回りに90°回転
#define vs_kaiten_l(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転


#define vvl_tenti(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][i]=v[i][j];swap(nx,v);}
#define vs_tenti(v) {ll n = size(v); vs nx(n, string(n,'.')); rep(i, n)rep(j, n)nx[j][i] = v[i][j]; swap(nx, v);}

//--------------------------------




//-----------5.数学系--------------
#define yu_qurid(x,y) ((x)*(x)+(y)*(y))//ユークリッド距離 sqrtはしてないなので注意
#define mannhattan(x1,x2,y1,y2) (abs(x1-x2)+abs(y1-y2)) // マンハッタン距離 = |x1-x2|+|y1-y2|

template<class T>T tousa_sum1(T l, T d, T r) {//初項,公差,末項 で総和を求める
    T wide = (r - l) / d + 1;
    return (l + r) * wide / 2;
}
template<class T>T tousa_sum2(T a, T d, T n) {//初項,交差,項数 で総和を求める
    return (a * 2 + d * (n - 1)) * n / 2;
}
ll kousa_kousuu(ll l, ll r, ll d) {//初項,末項,交差 で等差数列の項数を求める
    return (r - l) / d + 1;
}
// mint touhi_sum(mint a, mint r, ll n) {//初項,公比,項数で等比数列の総和を求める
//     if (r == 1) {
//         return a * n;
//     }
//     mint bunsi = a * (r.pow(n) - mint(1));
//     mint bunbo = r - 1;
//     return bunsi / bunbo;
// }

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

//----------------------------------------------




//-----------6.デバックや出力系------------------
void print(ld x) { printf("%.20Lf\n", x); }

void mukou_debug(vvl to, bool yukou) {//GRAPH × GRAPH用の無向グラフを出力する
    ll n = size(to); ll cnt = 0;//辺の本数
    vc<pair<ll, ll>>v; rep(i, n)for (ll t : to[i])  if (i < t || yukou)cnt++, v.eb(i + 1, t + 1);//有向グラフなら全部OK、違うなら無向なのでf<tのみ見る、using Pのやつを別のにしたいときのためにPを使わずにpair<ll,ll>にしてる
    cout << n << ' ' << cnt << endl; for (auto [f, t] : v)cout << f << ' ' << t << endl;
}

#define vc_cout(v){ll n = size(v);rep(i,n)cout<<v[i]<<endl;}//一次元配列を出力する
#define vv_cout(v){ll n = size(v);rep(i,n){rep(j,size(v[i])){cout<<v[i][j]<<' ';}cout<<endl;}}//二次元配列を出力する

template <typename T>
struct BIT {
    int n;          // 配列の要素数(数列の要素数+1)
    vector<T> bit;  // データの格納先
    BIT(int n_) : n(n_ + 1), bit(n, 0) {}
    void add(int i, T x) {
        i++;
        for (int idx = i; idx < n; idx += (idx & -idx)) {
            bit[idx] += x;
        }
    }
    // 0番目からl－1番目までの累積和
    T sum(int i) {
        T s(0);
        for (int idx = i; idx > 0; idx -= (idx & -idx)) {
            s += bit[idx];
        }
        return s;
    }
    // [l, r)の要素の総和
    T sum(int l, int r){
        T ret_l = sum(l);
        T ret_r = sum(r);
        return ret_r - ret_l;
    }

    // 累積和が x 以上になる最小のインデックスを返す(x >= 0)
    int lower_bound(T x) {
        int idx = 0;
        int k = 1;
        while (k * 2 < n) k *= 2; // 最大の 2^k

        for (; k > 0; k /= 2) {
            if (idx + k < n && bit[idx + k] < x) {
                x -= bit[idx + k];
                idx += k;
            }
        }
        return idx; // 0-indexed int idx = 0;
    }
};

int main(){
    string s;
    ll k;
    cin >> s >> k;
    ll n = s.size();
    vc<set<ll>> v(26, set<ll>());

    BIT<ll> bit(n);

    rep(i, n){
        v[s[i] - 'a'].insert(i);
    }

    rep(i, n){
        rep(j, 26){
            if(v[j].size() == 0) continue;
            ll idx = *v[j].begin();
            ll flg = idx - bit.sum(idx);
            if(flg > k) continue;
            k -= flg;
            cout << char('a' + j);
            v[j].erase(idx);
            bit.add(idx, 1);
            break;
        }
    }
    cout << endl;

    

    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 14300
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
int n;
long long m;
string s;
const int N = 3e5 + 10;

int son[N][2], sz[N], fa[N], idx;
char val[N];
pair<char,int> mn[N];

#define ls son[p][0]
#define rs son[p][1]

void pushup(int p) {
	if (ls == 0 && rs == 0) {
		mn[p] = make_pair(val[p], p);
	} else if (ls == 0) {
		if (val[p] <= mn[rs].first) {
			mn[p] = make_pair(val[p], p);
		} else mn[p] = mn[rs];
	} else if (rs == 0) {
		if (val[p] < mn[ls].first) {
			mn[p] = make_pair(val[p], p);
		} else mn[p] = mn[ls];
	} else {
		vector<tuple<char,int,int>> tmp(3);
		tmp[0] = make_tuple(mn[ls].first, 0, mn[ls].second);
		tmp[1] = make_tuple(val[p], 1, p);
		tmp[2] = make_tuple(mn[rs].first, 2, mn[rs].second);
		sort(tmp.begin(), tmp.end());
		mn[p] = make_pair(get<0>(tmp.front()), get<2>(tmp.front()));
	}
	sz[0] = 0;
	sz[p] = sz[ls] + sz[rs] + 1; 
}

void rotate(int p) {
	int f = fa[p], ff = fa[f], k = (p == son[f][1]);
	son[ff][f == son[ff][1]] = p;
	son[f][k] = son[p][k ^ 1], fa[son[p][k ^ 1]] = f;
	son[p][k ^ 1] = f;
	fa[f] = p; fa[p] = ff;
	pushup(f);
	pushup(p);
}
int root;

void splay(int p, int t) {
	int cnt = 0;
	for (int f; f = fa[p], t != f; rotate(p)) {
		if (fa[f] != t) rotate((son[fa[f]][1] == f) == (son[f][1] == p) ? f : p);
	}
	if (!t) root = p;
}

int pre(int p) {
	splay(p, 0);
	int res = ls;
	while (son[res][1]) res = son[res][1];
	return res;
}
int nxt(int p) {
	splay(p, 0);
	int res = rs;
	while (son[res][0]) res = son[res][0];
	return res;
}

int getidbyrk(int rk) {
	++rk;
	int p = root;
	sz[0] = 0;
	while (1) {
		if (sz[ls] >= rk) p = ls;
		else if (sz[ls] + 1 >= rk) break;
		else rk -= sz[ls] + 1, p = rs;
	}
	splay(p, 0);
	return p;
}
void del(int p) {
	int pr = pre(p);
	int nt = nxt(p);
	splay(pr, 0);
//		cout << root << ':' << endl;
//	for (int _ = 1; _ <= idx; _++) {
//		cout << _ << ',' << val[_] << ',' << son[_][0] << ',' << son[_][1] << ',' << fa[_] << ',' << sz[_] << endl;
//	}
	splay(nt, pr);
	son[nt][0] = 0;
	pushup(nt);
	pushup(pr);
}

void insert(int rk, char c) {
	int p = getidbyrk(rk);
	int nt = nxt(p);
	splay(p, 0);
	splay(nt, p);
	son[nt][0] = ++idx;
	fa[idx] = nt;
	val[idx] = c;
	pushup(idx);
	pushup(nt);
	pushup(p);
}

pair<char,int> query(int l, int r) {
	l = getidbyrk(l); 
	r = getidbyrk(r);
	int pr = pre(l);
	int nt = nxt(r);
	splay(pr, 0);
	splay(nt, pr);
	return mn[son[nt][0]];
}

int getrkbyid(int p) {
	splay(p, 0);
	return sz[ls];
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	root = idx = 2;
	fa[1] = 2;
	son[2][0] = 1;
	val[1] = 127;
	val[2] = 127;
	pushup(1);
	pushup(2);
	cin >> s >> m;
	n = s.length();
	s = ' ' + s;
	for (int i = 1; i <= n; i++) {
		insert(i - 1, s[i]);
	}
//	for (int i = 1; i <= n; i++) {
//		cout << val[getidbyrk(i)] << endl;
//	}
//	cout << root << ':' << endl;
//	for (int _ = 1; _ <= idx; _++) {
//		cout << _ << ',' << val[_] << ',' << son[_][0] << ',' << son[_][1] << ',' << fa[_] << ',' << sz[_] << endl;
//	}
	for (int i = 1; i < n; i++) {
		if (m == 0) break;
		int l = i + 1;
		int r = min((long long) n, i + m);
		auto res = query(l, r);
		if (res.first >= val[getidbyrk(i)]) continue;
		m -= getrkbyid(res.second) - i; 
		del(res.second);
		insert(i - 1, res.first); 
	}
	for (int i = 1; i <= n; i++) {
		cout << val[getidbyrk(i)];
	}
	cout << endl;
    return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 9664
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using lli=long long int;
using vi=vector<int>;
using vvi=vector<vi>;
using vvvi=vector<vvi>;
using vl=vector<lli>;
using vvl=vector<vl>;
#define all(s) s.begin(),s.end()
#define rall(s) s.rbegin(),s.rend()
#define rep(i,s,e) for(int i=s;i<e;i++)
#define rrep(i,s,e) for(int i=s-1;i>=e;i--)
#define in(v,seq) for(auto v:seq)
#define pub(x) push_back(x)
#define puf(x) push_front(x)
#define pob(x) pop_back(x)
#define pof(x) pop_front(x)
#define emb(x) emplace_back(x)
#define print(s) cout << s << endl;
const string alp="abcdefghijklmnopqrstuvwxyz";
const int let=alp.size(); // 26

template<typename S> struct ST{
  function<S(S,S)> op; // calc
  S e; // monoid
  int n; // size of bottom
  vector<int> val;
  vector<S> data; // save value

  // initialization
  ST(int N,function<S(S,S)> op,S e):op(op),e(e){
    n=1;
    while(n<N) n*=2;
    data.assign(2*n,e);
    val.assign(2*n,0);
  }
  ST(vector<S> a,function<S(S,S)> op,S e):op(op),e(e){
    n=1;
    while(n<(int)a.size()) n*=2;
    data.assign(2*n,e);
    val.assign(2*n,0);
    
    for(int i=0;i<(int)a.size();i++){
      data.at(i+n)=a.at(i);
    }
    for(int i=n-1;i>0;i--){
      data.at(i)=op(data.at(2*i),data.at(2*i+1));
    }
  }

  void set(int i,S v){
    i+=n; data.at(i)=v;
    while(i>1){
      i/=2;
      data.at(i)=op(data.at(2*i),data.at(2*i+1));
    }
  }
  S at(int i){
    return data.at(i+n);
  }
  // [l,r)
  S calc(int l,int r){
    return pre_calc(l,r,1,0,n);
  }
  // recursive function
  S pre_calc(int l,int r,int k,int a,int b){
    if(r<=a || b<=l) return e;
    if(l<=a && b<=r) return data.at(k);
    return op(pre_calc(l,r,k*2,a,(a+b)/2),pre_calc(l,r,k*2+1,(a+b)/2,b));
  }

  void plus(int i,int a){
    i+=n; val.at(i)+=a;
    while(i>1){
      i/=2;
      val.at(i)=val.at(2*i)+val.at(2*i+1);
    }
  }

  int sum(int b){
    return pre_sum(b,n,1,0,n);
  }

  int pre_sum(int l,int r,int k,int a,int b){
    if(r<=a || b<=l) return 0;
    if(l<=a && b<=r) return val.at(k);
    return pre_sum(l,r,k*2,a,(a+b)/2)+pre_sum(l,r,k*2+1,(a+b)/2,b);
  }
};

char e='z'+1;
char op(char a,char b){ return min(a,b); }


int main(){
  string Str; cin >> Str;
  vector<char> s(Str.begin(),Str.end());
  int n=Str.size(),k; cin >> k;
  
  vvi v(let);
  vi cnt(let);
  ST<char> stree(s,op,e);
  rep(i,0,n){
    v.at(s.at(i)-'a').pub(i);
  }

  string ans="";
  rep(i,0,n){
    int l=0,r=n;
    while(l<r){
      int mid=(l+r)/2;
      if(mid-i+stree.sum(mid)>k){
        r=mid;
      }else{
        l=mid+1;
      }
    }

    char c=stree.calc(0,l);
    ans+=c;
    int ind=v.at(c-'a').at(cnt.at(c-'a'));
    cnt.at(c-'a')++;
    k-=ind-i+stree.sum(ind);
    stree.set(ind,e);
    stree.plus(ind,1);
  }

  print(ans);
}
accuracy: 1
time_ms: 180
memory_kb: 7644
final_rank: 13

code_snippet: #pragma region Macros
 
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,fma,abm,mmx,avx,avx2,popcnt")
 
#include <bits/extc++.h>
// #include <atcoder/all>
// using namespace atcoder;
using namespace std;
using namespace __gnu_pbds;
 
// #include <boost/multiprecision/cpp_dec_float.hpp>
// #include <boost/multiprecision/cpp_int.hpp>
// namespace mp = boost::multiprecision;
// using Bint = mp::cpp_int;
// using Bdouble = mp::number<mp::cpp_dec_float<256>>;
// Bdouble Beps = 0.00000000000000000000000000000001; // 1e-32
// const bool equals(Bdouble a, Bdouble b) { return mp::fabs(a - b) < Beps; }

#define pb emplace_back
#define int ll
#define endl '\n'
 
#define sqrt __builtin_sqrtl
#define cbrt __builtin_cbrtl
#define hypot __builtin_hypotl
 
// #define next asdnext
// #define prev asdprev
 
using ll = long long;
using ld = long double;
const ld PI = acosl(-1);
const int INF = 1 << 30;
const ll INFL = 1LL << 61;
const int MOD = 998244353;
// const int MOD = 1000000007;

const ld EPS = 1e-10;
const bool equals(ld a, ld b) { return fabs((a) - (b)) < EPS; }
 
const vector<int> dx = {0, 1, 0, -1, 1, 1, -1, -1}; // → ↓ ← ↑ ↘ ↙ ↖ ↗
const vector<int> dy = {1, 0, -1, 0, 1, -1, -1, 1};
 
#define EC int
struct Edge {
    int from, to;
    EC cost;
    Edge() : from(-1), to(-1), cost(-1) {}
    Edge(int to, EC cost) : to(to), cost(cost) {}
    Edge(int from, int to, EC cost) : from(from), to(to), cost(cost) {}
    bool operator ==(const Edge& e) {
        return this->from == e.from && this->to == e.to && this->cost == e.cost;
    }
    bool operator !=(const Edge& e) {
        return this->from != e.from or this->to != e.to or this->cost != e.cost;
    }
    bool operator <(const Edge& e) { return this->cost < e.cost; }
    bool operator >(const Edge& e) { return this->cost > e.cost; }
};
 
chrono::system_clock::time_point start;
__attribute__((constructor))
void constructor() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    start = chrono::system_clock::now();
}
 
random_device seed_gen;
mt19937_64 rng(seed_gen());
uniform_int_distribution<int> dist_x(0, 1e9);
struct RNG {
    unsigned Int() {
        return dist_x(rng);
    }
    unsigned Int(unsigned l, unsigned r) {
        return dist_x(rng) % (r - l + 1) + l;
    }
    ld Double() {
        return ld(dist_x(rng)) / 1e9;
    }
} rnd;

namespace bit_function {
    using i64 = ll;
    // using i64 = uint64_t;
    // bit演算, x==0の場合は例外処理した方がよさそう. 区間は [l, r)
    i64 lrmask(int l, int r) { return (1LL << r) - (1LL << l); }
    i64 sub_bit(i64 x, int l, int r) { i64 b = x & ((1LL << r) - (1LL << l)); return b >> l; } // r溢れ可
    i64 bit_width(i64 x) { return 64 - __builtin_clzll(x) + (x == 0); }
    
    i64 popcount(i64 x) { return __builtin_popcountll(x); }
    i64 popcount(i64 x, int l, int r) { return __builtin_popcountll(sub_bit(x, l, r)); }
    i64 unpopcount(i64 x) { return bit_width(x) - __builtin_popcountll(x); } // 最上位bitより下のみ
    i64 unpopcount(i64 x, int l, int r) { return r - l - __builtin_popcountll(sub_bit(x, l, r)); } // 最上位bitより上も含まれうる
    bool is_pow2(i64 x) { return __builtin_popcountll(x) == 1; } // xが負のときは常にfalse
    bool is_pow4(i64 x) { return __builtin_popcountll(x) == 1 && __builtin_ctz(x) % 2 == 0; }
    //bool is_pow4(ll x) { return __builtin_popcountll(x) == 1 && (x&0x55555555); }
    
    int top_bit(i64 x) { return 63 - __builtin_clzll(x);} // 2^kの位 (x > 0)
    int bot_bit(i64 x) { return __builtin_ctzll(x);} // 2^kの位 (x > 0)
    int next_bit(i64 x, int k) { // upper_bound
        x >>= (k + 1);
        int pos = k + 1;
        while (x > 0) {
            if (x & 1) return pos;
            x >>= 1;
            pos++;
        }
        return -1;
    }
    int prev_bit(i64 x, int k) {
        // k = min(k, bit_width(x)); ?
        int pos = 0;
        while (x > 0 && pos < k) {
            if (x & 1) {
                if (pos < k) return pos;
            }
            x >>= 1;
            pos++;
        }
        return -1;
    }
    int kth_bit(i64 x, int k) { // kは1-indexed
        int pos = 0, cnt = 0;
        while (x > 0) {
            if (x & 1) {
                cnt++;
                if (cnt == k) return pos;
            }
            x >>= 1;
            pos++;
        }
        return -1;
    }
    i64 msb(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // mask
    i64 lsb(i64 x) { return (x & -x); } // mask
    
    int countl_zero(i64 x) { return __builtin_clzll(x); }
    int countl_one(i64 x) { // countl_oneと定義が異なるので注意
        i64 ret = 0, k = 63 - __builtin_clzll(x);
        while (k != -1 && (x & (1LL << k))) { k--; ret++; }
        return ret;
    }
    int countr_zero(i64 x) { return __builtin_ctzll(x); } // x=0のとき64
    int countr_one(i64 x) { int ret = 0; while (x & 1) { x >>= 1; ret++; } return ret; }
    // int countr_one(ll x) { return __builtin_popcount(x ^ (x & -~x));

    i64 l_one(i64 x) { // 最上位で連なってる1のmask
        if (x == 0) return 0;
        i64 ret = 0, k = 63 - __builtin_clzll(x);
        while (k != -1 && (x & (1LL << k))) { ret += 1LL << k; k--; }
        return ret;
    }
    
    int floor_log2(i64 x) { return 63 - __builtin_clzll(x); } // top_bit
    int ceil_log2(i64 x) { return 64 - __builtin_clzll(x - 1); }
    i64 bit_floor(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // msb
    i64 bit_ceil(i64 x) { if (x == 0) return 0; return 1LL << (64 - __builtin_clzll(x - 1)); }
    
    i64 rotl(i64 x, int k) { // 有効bit内でrotate. オーバーフロー注意
        i64 w = bit_width(x); k %= w;
        return ((x << k) | (x >> (w - k))) & ((1LL << w) - 1);
    }
    // i64 rotl(i64 x, i64 l, i64 m, i64 r) {}
    i64 rotr(i64 x, int k) {
        i64 w = bit_width(x); k %= w;
        return ((x >> k) | (x << (w - k))) & ((1LL << w) - 1);
    }
    // i64 rotr(i64 x, i64 l, i64 m, i64 r) {}
    i64 bit_reverse(i64 x) { // 有効bit内で左右反転
        i64 r = 0, w = bit_width(x);
        for (i64 i = 0; i < w; i++) r |= ((x >> i) & 1) << (w - i - 1);
        return r;
    }
    // i64 bit_reverse(i64 x, int l, int r) {}
    
    bool is_palindrome(i64 x) { return x == bit_reverse(x); }
    bool is_palindrome(i64 x, int l, int r) { i64 b = sub_bit(x, l, r); return b == bit_reverse(b); }
    i64 concat(i64 a, i64 b) { return (a << bit_width(b)) | b; } // オーバーフロー注意
    i64 erase(i64 x, int l, int r) { return x >> r << l | x & ((1LL << l) - 1); } // [l, r) をカット
    
    i64 hamming(i64 a, i64 b) { return __builtin_popcountll(a ^ b); }
    i64 hamming(i64 a, i64 b, int l, int r) { return __builtin_popcountll(sub_bit(a, l, r) ^ sub_bit(b, l, r)); }
    i64 compcount(i64 x) { return (__builtin_popcountll(x ^ (x >> 1)) + (x & 1)) / 2; }
    i64 compcount2(i64 x) { return compcount(x & (x >> 1)); } // 長さ2以上の連結成分の個数
    i64 adjacount(i64 x) { return __builtin_popcountll(x & (x >> 1)); } // 隣接する1のペアの個数
    
    i64 next_combination(i64 x) {
        i64 t = x | (x - 1); return (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctzll(x) + 1));
    }
} using namespace bit_function;

namespace util_function {
    namespace Std = std;
    __int128_t POW(__int128_t x, int n) {
        __int128_t ret = 1;
        assert(n >= 0);
        if (x == 1 or n == 0) ret = 1;
        else if (x == -1 && n % 2 == 0) ret = 1; 
        else if (x == -1) ret = -1; 
        else if (n % 2 == 0) {
            // assert(x < INFL);
            ret = POW(x * x, n / 2);
        } else {
            // assert(x < INFL);
            ret = x * POW(x, n - 1);
        }
        return ret;
    }
    int per(int x, int y) { // x = qy + r (0 <= r < y) を満たすq
        assert(y != 0);
        if (x >= 0 && y > 0) return x / y;
        if (x >= 0 && y < 0) return x / y - (x % y < 0);
        if (x < 0 && y < 0) return x / y + (x % y < 0);
        return x / y - (x % y < 0); //  (x < 0 && y > 0) 
    }
    int mod(int x, int y) { // x = qy + r (0 <= r < y) を満たすr
        assert(y != 0);
        return x - y * per(x, y);
    } // https://yukicoder.me/problems/no/2781
    int floor(int x, int y) { // (ld)x / y 以下の最大の整数
        assert(y != 0);
        if (y < 0) x = -x, y = -y;
        return x >= 0 ? x / y : (x + 1) / y - 1;
    }
    int ceil(int x, int y) { // (ld)x / y 以上の最小の整数
        assert(y != 0);
        if (y < 0) x = -x, y = -y;
        return x > 0 ? (x - 1) / y + 1 : x / y;
    }
    int round(int x, int y) { // (ld)(x/y)を小数点第1位について四捨五入
        assert(y != 0);
        return (x * 2 + y) / (y * 2);
    }
    int round(int x, int y, int k) { // (ld)(x/y)を10^kの位に関して四捨五入
        assert(y != 0 && k >= 0);
        if (k == 0) return (x * 2 + y) / (y * 2);
        x /= y * POW(10, k - 1);
        if (x % 10 >= 5) return (x + 10 - x % 10) * POW(10, k - 1);
        return x * POW(10, k - 1);
    }
    int round2(int x, int y) { // 五捨五超入 // 未verify
        assert(y != 0);
        if (y < 0) y = -y, x = -x;
        int z = x / y;
        if ((z * 2 + 1) * y <= y * 2) z++;
        return z;
    }
    ld round(ld x, int k) { // xを10^kの位に関して四捨五入. to_string(x, k)優先
        // x += EPS;
        ld d = pow(10, -k);
        return Std::round(x * d) / d;
    }
    ld floor(ld x, int k) { // xを10^kの位に関してflooring
        // x += EPS;
        ld d = pow(10, -k);
        return Std::floor(x * d) / d; // 未verify
    }
    ld ceil(ld x, int k) { // xを10^kの位に関してceiling
        // x -= EPS;
        ld d = pow(10, -k);
        return Std::ceil(x * d) / d; // 未verify
    }
    // int kth(int x, int y, int k) { // x / yの10^kの位の桁
    // }
    int floor(ld x, ld y) { // 誤差対策TODO
        assert(!equals(y, 0));
        return Std::floor(x / y);
        // floor(x) = ceil(x - 1) という話も
    }
    int ceil(ld x, ld y) { // 誤差対策TODO // ceil(p/q) = -floor(-(p/q))らしい
        assert(!equals(y, 0));
        return Std::ceil(x / y);
        // ceil(x) = floor(x + 1)
    }
    int perl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす q
        // 未verify. 誤差対策TODO. EPS外してもいいかも。
        assert(!equals(y, 0));
        if (x >= 0 && y > 0) return Std::floor(x / y)+EPS;
        if (x >= 0 && y < 0) return -Std::floor(x / fabs(y));
        if (x < 0 && y < 0) return Std::floor(x / y) + (x - Std::floor(x/y)*y < -EPS);
        return Std::floor(x / y) - (x - Std::floor(x/y)*y < -EPS); //  (x < 0 && y > 0) 
    }
    ld modl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす r
        // 未verify. 誤差対策TODO. -0.0が返りうる。
        assert(!equals(y, 0));
        if (x >= 0) return x - fabs(y)*fabs(per(x, y));
        return x - fabs(y)*floor(x, fabs(y));
    }
    int seisuu(ld x) { return (int)x; } // 整数部分. 誤差対策TODO
    int modf(ld x) {
        if (x < 0) return ceill(x);
        else return floorl(x);
    }
    // 正なら+EPS, 負なら-EPSしてから、文字列に直して小数点以下を捨てる?
    int seisuu(int x, int y) {
        assert(y != 0);
        return x / y;
    }
    int seisuu(ld x, ld y) { // 誤差対策TODO
        assert(!equals(y, 0));
        return (int)(x / y);
    }

    int floor_log(int base, int x) {
        assert(base >= 2);
        int ret = 0, now = 1;
        while (now <= x) {
            now *= base;
            if (now <= x) ret++;
        }
        return ret;
    }
    int ceil_log(int base, int x) {
        assert(base >= 2);
        int ret = 0, now = 1;
        while (now < x) {
            now *= base;
            ret++;
        }
        return ret;
    }

    template <class T> pair<T, T> max(const pair<T, T> &a, const pair<T, T> &b) {
        if (a.first > b.first or a.first == b.first && a.second > b.second) return a;
        return b;
    }
    template <class T> pair<T, T> min(const pair<T, T> &a, const pair<T, T> &b) {
        if (a.first < b.first or a.first == b.first && a.second < b.second) return a;
        return b;
    }
    
    template <class T> bool chmax(T &a, const T& b) {
        if (a < b) { a = b; return true; } return false;
    }
    template <class T> bool chmin(T &a, const T& b) {
        if (a > b) { a = b; return true; } return false;
    }
    template <class T> T mid(T a, T b, T c) { // 誤差対策TODO
        return a + b + c - Std::max({a, b, c}) - Std::min({a, b, c});
    }
    template <class T> void Sort(T &a, T &b, bool rev = false) { 
        if (rev == false) if (a > b) swap(a, b);
        else if (b > a) swap(b, a);
    }
    template <typename T, typename... Args>
    void Sort(T& a, T& b, T& c, Args&... args) {
        vector<T> vec = {a, b, c, args...};
        sort(vec.begin(), vec.end());
        auto it = vec.begin();
        a = *it++; b = *it++; c = *it++;
        int dummy[] = { (args = *it++, 0)... };
        static_cast<void>(dummy);
    }
    template <typename T, typename... Args>
    void Sortr(T& a, T& b, T& c, Args&... args) {
        vector<T> vec = {a, b, c, args...};
        sort(vec.rbegin(), vec.rend());
        auto it = vec.begin();
        a = *it++; b = *it++; c = *it++;
        int dummy[] = { (args = *it++, 0)... };
        static_cast<void>(dummy);
    }

    istream &operator >>(istream &is, __int128_t& x) {
        string S; is >> S;
        __int128_t ret = 0;
        int f = 1;
        if (S[0] == '-') f = -1; 
        for (int i = 0; i < S.length(); i++)
            if ('0' <= S[i] && S[i] <= '9')
                ret = ret * 10 + S[i] - '0';
        x = ret * f;
        return (is);
    }
    ostream &operator <<(ostream &os, __int128_t x) {
        ostream::sentry s(os);
        if (s) {
            __uint128_t tmp = x < 0 ? -x : x;
            char buffer[128]; char *d = end(buffer);
            do {
                --d; *d = "0123456789"[tmp % 10]; tmp /= 10;
            } while (tmp != 0);
            if (x < 0) { --d; *d = '-'; }
            int len = end(buffer) - d;
            if (os.rdbuf()->sputn(d, len) != len) os.setstate(ios_base::badbit);
        }
        return os;
    }
    
    __int128_t stoll(string &S) {
        __int128_t ret = 0; int f = 1;
        if (S[0] == '-') f = -1; 
        for (int i = 0; i < S.length(); i++)
            if ('0' <= S[i] && S[i] <= '9') ret = ret * 10 + S[i] - '0';
        return ret * f;
    }
    __int128_t gcd(__int128_t a, __int128_t b) { return b ? gcd(b, a % b) : a; }
    __int128_t lcm(__int128_t a, __int128_t b) {
        return a / gcd(a, b) * b;
        // lcmが__int128_tに収まる必要あり
    }
    
    string to_string(ld x, int k) { // xの小数第k位までをstring化する
        assert(k >= 0);
        stringstream ss;
        ss << setprecision(k + 2) << x;
        string s = ss.str();
        if (s.find('.') == string::npos) s += '.';
        int pos = s.find('.');
        for (int i = 0; k >= (int)s.size() - 1 - pos; i++) s += '0';
        s.pop_back();
        if (s.back() == '.') s.pop_back();
        return s;
    
        // stringstream ss; // 第k+1位を四捨五入して第k位まで返す
        // ss << setprecision(k + 1) << x;
        // string s = ss.str();
        // if (s.find('.') == string::npos) s += '.';
        // int pos = s.find('.');
        // for (int i = 0; k > (int)s.size() - 1 - pos; i++) s += '0';
        // if (s.back() == '.') s.pop_back();
        // return s;
    }
    string to_string(__int128_t x) {
        string ret = "";
        if (x < 0) { ret += "-"; x *= -1; }
        while (x) { ret += (char)('0' + x % 10); x /= 10; }
        reverse(ret.begin(), ret.end());
        return ret;
    }
    string to_string(char c) { string s = ""; s += c; return s; }
} using namespace util_function;

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
 
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

template<class T> size_t HashCombine(const size_t seed,const T &v) {
    return seed^(hash<T>()(v)+0x9e3779b9+(seed<<6)+(seed>>2));
}
template<class T,class S> struct hash<pair<T,S>>{
    size_t operator()(const pair<T,S> &keyval) const noexcept {
        return HashCombine(hash<T>()(keyval.first), keyval.second);
    }
};
template<class T> struct hash<vector<T>>{
    size_t operator()(const vector<T> &keyval) const noexcept {
        size_t s=0;
        for (auto&& v: keyval) s=HashCombine(s,v);
        return s;
    }
};
template<int N> struct HashTupleCore{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{
        size_t s=HashTupleCore<N-1>()(keyval);
        return HashCombine(s,get<N-1>(keyval));
    }
};
template <> struct HashTupleCore<0>{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{ return 0; }
};
template<class... Args> struct hash<tuple<Args...>>{
    size_t operator()(const tuple<Args...> &keyval) const noexcept {
        return HashTupleCore<tuple_size<tuple<Args...>>::value>()(keyval);
    }
};

template<typename T>
class Compress { // 試験運用, バグったらTをintにする
public:
    int sz = 0;
    // gp_hash_table<T, int, custom_hash> Z;
    // gp_hash_table<int, T, custom_hash> UZ;
    unordered_map<T, int> Z;    // 元の値 -> 圧縮した値
    unordered_map<int, T> UZ;   // 圧縮した値 -> 元の値
 
    Compress() {}
    Compress(const vector<T> &V, T base = 0) {
        this->sz = base;
        set<T> s(V.begin(), V.end());
 
        for (T x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
    
    Compress(const vector<T> &V1, const vector<T> &V2, T base = 0) {
        this->sz = base;
        vector<T> V3 = V2;
        V3.insert(V3.end(), V1.begin(), V1.end());
        set<T> s(V3.begin(), V3.end());
 
        for (T x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<T> &V1, const vector<T> &V2, const vector<T> &V3, T base = 0) {
        this->sz = base;
        vector<T> V4 = V1;
        V4.insert(V4.end(), V2.begin(), V2.end());
        V4.insert(V4.end(), V3.begin(), V3.end());
        set<T> s(V4.begin(), V4.end());
 
        for (T x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<T> &V1, const vector<T> &V2,
            const vector<T> &V3, const vector<T> &V4, T base = 0) {
        this->sz = base;
        vector<T> V5 = V1;
        V5.insert(V5.end(), V2.begin(), V2.end());
        V5.insert(V5.end(), V3.begin(), V3.end());
        V5.insert(V5.end(), V4.begin(), V4.end());
        set<T> s(V5.begin(), V5.end());
 
        for (T x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    vector<int> zip(const vector<T> &V) {
        vector<int> ret(V.size());
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = Z[V[i]];
        }
        return ret;
    }
 
    vector<T> unzip(const vector<int> &V) {
        vector<T> ret(V.size());
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = UZ[V[i]];
        }
        return ret;
    }
 
    int size() { return sz; }
 
    T encode(int x) { return Z[x]; }
    int decode(T x) {
        if (UZ.find(x) == UZ.end()) return -1; // xが元の配列に存在しないとき
        return UZ[x];
    }
};
 
 
#pragma endregion

// https://atcoder.jp/contests/abc350/submissions/52583195
template <class S, S(*op)(S, S), S(*e)(), class F, S(*act)(F, S), F(*comp)(F, F), F(*id)()>
class Implicit_treap {
	inline static bool first_call = true;
	inline static mt19937 rnd;

	struct Node {
		S value;				// 頂点の値
		S acc;					// 部分木のノードの総和
		F lazy;					// 部分木のノードへの遅延作用
		uint64_t priority;	    // ランダムに決めた優先度. 多分uint32_tで十分
		int cnt;				// 部分木のノード数
		bool rev;				// 部分木が反転されているか
		Node* l, * r;			// 左右の子へのポインタ
		Node(S value, uint64_t priority) : value(value), acc(e()), lazy(id()), priority(priority),
			cnt(1), rev(false), l(nullptr), r(nullptr) {}
	};

	Node* root;

	int cnt(Node* t) {
		return t ? t->cnt : 0;
	}

	S acc(Node* t) {
		return t ? t->acc : e();
	}

	void update_cnt(Node* t) {
		if (t) t->cnt = cnt(t->l) + 1 + cnt(t->r);
	}

	void update_acc(Node* t) {
		if (t) t->acc = op(acc(t->l), op(t->value, acc(t->r)));
	}

	void pushup(Node* t) {
		update_cnt(t);
		update_acc(t);
	}

	void pushdown(Node* t) {
		if (t && t->rev) {
			t->rev = false;
			swap(t->l, t->r);
			if (t->l) t->l->rev ^= 1;
			if (t->r) t->r->rev ^= 1;
		}
		if (t && t->lazy != id()) {
			if (t->l) {
				t->l->lazy = comp(t->lazy, t->l->lazy);
				t->l->acc = act(t->lazy, t->l->acc);
			}
			if (t->r) {
				t->r->lazy = comp(t->lazy, t->r->lazy);
				t->r->acc = act(t->lazy, t->r->acc);
			}

			t->value = act(t->lazy, t->value);
			t->lazy = id();
		}
		pushup(t);
	}

	void split(Node* t, int key, Node*& l, Node*& r) {
		if (!t) {
			l = r = nullptr;
			return;
		}
		pushdown(t);
		int implicit_key = cnt(t->l);

		if (key <= implicit_key) {
			split(t->l, key, l, t->l);
			r = t;
		}
		else {
			split(t->r, key - implicit_key - 1, t->r, r);
			l = t;
		}
		pushup(t);
	}

	void merge(Node*& t, Node* l, Node* r) {
		pushdown(l);
		pushdown(r);
		if (!l) t = r;
		else if (!r) t = l;
		else if (l->priority > r->priority) {
			merge(l->r, l->r, r);
			t = l;
		}
		else {
			merge(r->l, l, r->l);
			t = r;
		}

		pushup(t);
	}

	void get_all(Node* t, vector<S>& seq) {
		if (!t) return;
		pushdown(t);
		get_all(t->l, seq);
		seq.emplace_back(t->value);
		get_all(t->r, seq);
	}

public:
	Implicit_treap() : root(nullptr) {
		if (Implicit_treap::first_call) {
			rnd = mt19937((int)time(NULL));
			Implicit_treap::first_call = false;
		}
	}

	Implicit_treap(const vector<S>& a) : root(nullptr) {
		if (Implicit_treap::first_call) {
			rnd = mt19937((int)time(NULL));
			Implicit_treap::first_call = false;
		}

		for (int i = 0; i < a.size(); i++) {
			insert(i, a[i]);
		}
	}

	bool empty() {
		return !(bool)root;
	}

	int size() {
		return cnt(root);
	}

	void apply(int l, int r, F f) {
		if (l >= r) return;
		Node* lt, * mt, * rt;
		split(root, l, lt, rt);
		split(rt, r - l, mt, rt);
		if (mt) {
			mt->lazy = comp(f, mt->lazy);
			mt->acc = act(f, mt->acc);
		}
		merge(rt, mt, rt);
		merge(root, lt, rt);
	}

	void apply(int i, F f) {
		apply(i, i + 1, f);
	}

	S prod(int l, int r) {
		if (l >= r) return e();
		Node* lt, * mt, * rt;
		split(root, l, lt, rt);
		split(rt, r - l, mt, rt);
		S res = acc(mt);
		merge(rt, mt, rt);
		merge(root, lt, rt);

		return res;
	}

	S get(int i) {
		return prod(i, i + 1);
	}

	void insert(int i, S x) {
		Node* lt, * rt;
		split(root, i, lt, rt);
		merge(lt, lt, new Node(x, rnd()));
		merge(root, lt, rt);
	}

	void erase(int i) {
		Node* lt, * mt, * rt;
		split(root, i + 1, lt, rt);
		split(lt, i, lt, mt);
		merge(root, lt, rt);
	}

	void reverse(int l, int r) {
		if (l >= r) return;
		Node* lt, * mt, * rt;
		split(root, l, lt, rt);
		split(rt, r - l, mt, rt);
		mt->rev ^= 1;
		merge(rt, mt, rt);
		merge(root, lt, rt);
	}

	void rotate(int l, int m, int r) {
		reverse(l, r);
		reverse(l, l + r - m);
		reverse(l + r - m, r);
	}

	Implicit_treap split(int key) {
		Node* l, * r;
		split(root, key, l, r);
		root = l;
		Implicit_treap ret;
		ret.root = r;
		return ret;
	}

	void merge(Implicit_treap& IT) {
		merge(root, root, IT.root);
	}

	vector<S> get_all() {
		vector<S> seq;
		get_all(root, seq);
		return seq;
	}
};

using S = pair<int, int>;
S op(S x, S y) { return min({x, y}); }
S e() { return {INF, INF}; }

using F = int;
S mapping(F f, S x) { return {x.first, x.second + f}; }
F composition(F f, F g) { return f + g; }
F id() { return 0; }

signed main() {
    int K;
    string s;
    cin >> s >> K;
    int N = s.size();

    vector<S> A(N);
    for (int i = 0; i < N; i++) {
        A[i].first = s[i] - 'a';
        A[i].second = i;
    }

    Implicit_treap<S, op, e, F, mapping, composition, id> tr(A);

    int br = false;
    for (int i = 0; i < N; i++) {
        auto p = tr.prod(i, min(i + K + 1, N)); // (最小値, 最小値を取るindex)
        int dest = i;

        if (abs(dest - p.second) <= K) {
            tr.erase(p.second);
            tr.insert(i, {p.first, i});
            tr.apply(i + 1, p.second + 1, 1);
            K -= abs(dest - p.second);
        } else break;
    }

    vector<S> ret = tr.get_all();
    vector<int> ans(N);
    for (int i = 0; i < N; i++) ans[i] = ret[i].first;

    for (int i = 0; i < (int)ans.size(); i++) {
        cout << (char)('a' + ans[i]) << (i != (int)ans.size() - 1 ? "" : "\n");
    }
}
accuracy: 1
time_ms: 410
memory_kb: 50360
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

template<typename T,T e>
struct segtreesum {
	vector<long long> v;
	long long n;
	T f(T a,T b){
		return a + b;
	}
	segtreesum(long long n) : n(n) {
		v.resize(n * 2ll);
		for(long long i = 0ll;i < n * 2ll;i++){
			v[i] = e;
		}
	}
	segtreesum(vector<T> x) : n(x.size()) {
		v.resize(n * 2ll);
		for(long long i = 0ll;i < n;i++){
			v[i + n] = x[i];
		}
		for(long long i = n - 1;i >= 0;i--){
			v[i] = f(v[i * 2ll],v[i * 2ll + 1ll]);
		}
	}
	T operator[](long long a){
		return v[a + n];
	}
	void set(long long a,long long b){
		a += n;
		v[a] = b;
		while(a >>= 1ll){
			v[a] = f(v[a * 2ll],v[a * 2ll + 1ll]);
		}
	}
	T prod(long long l,long long r){
		T res = e;
		for(l += n,r += n;l < r;l >>= 1ll,r >>= 1ll){
			if(l & 1ll){
				res = f(res,v[l++]);
			}
			if(r & 1ll){
				res = f(res,v[--r]);
			}
		}
		return res;
	}
};
template<typename T,T e>
struct segtree {
	vector<long long> v;
	long long n;
	T f(T a,T b){
		return min(a,b);
	}
	segtree(long long n) : n(n) {
		v.resize(n * 2ll);
		for(long long i = 0ll;i < n * 2ll;i++){
			v[i] = e;
		}
	}
	segtree(vector<T> x) : n(x.size()) {
		v.resize(n * 2ll);
		for(long long i = 0ll;i < n;i++){
			v[i + n] = x[i];
		}
		for(long long i = n - 1;i >= 0;i--){
			v[i] = f(v[i * 2ll],v[i * 2ll + 1ll]);
		}
	}
	T operator[](long long a){
		return v[a + n];
	}
	void set(long long a,long long b){
		a += n;
		v[a] = b;
		while(a >>= 1ll){
			v[a] = f(v[a * 2ll],v[a * 2ll + 1ll]);
		}
	}
	T prod(long long l,long long r){
		T res = e;
		for(l += n,r += n;l < r;l >>= 1ll,r >>= 1ll){
			if(l & 1ll){
				res = f(res,v[l++]);
			}
			if(r & 1ll){
				res = f(res,v[--r]);
			}
		}
		return res;
	}
};
int main()
{
	string S;
	cin >> S;
	int n = S.size(),k;
	vector<int> s(n);
	for(int i = 0;i < n;i++){
		s[i] = S[i];
	}
	cin >> k;
	segtree<int,'z' + 1> seg(s);
	segtreesum<int,0> cou(n);
	string ans = "";
	for(int i = 0;i < n;i++){
		int low = 0,high = n - 1;
		while(low < high){
			int mid = (low + high + 1) / 2;
			if(mid - cou.prod(0,mid + 1) <= k){
				low = mid;
			}else{
				high = mid - 1;
			}
		}
		int it = seg.prod(0,low + 1);
		low = 0;
		while(low < high){
			int mid = (low + high) / 2;
			if(seg.prod(0,mid + 1) != it){
				low = mid + 1;
			}else{
				high = mid;
			}
		}
		int pos = low;
		k -= pos - cou.prod(0,pos + 1);
		ans += (char)it;
		cou.set(pos,1);
		seg.set(pos,'z' + 1);
	}
	cout << ans << endl;
}
accuracy: 1
time_ms: 210
memory_kb: 10848
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define rep(i, m, n) for (int i = (int)(m); i < (int)(n); i++)

template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }

int n0;
int a[100009];

int INF = 0;

typedef long long ll;
#define all(v) v.begin(), v.end()

// sort(a.begin(), a.end());
// long long x = lower_bound(a.begin(), a.end(), t) - a.begin();

class segment_tree {
private:
	int size;
	vector<ll> v;
public:
	segment_tree(vector<ll> w) {
		n0 = 1; while (n0 < w.size()) n0 *= 2;
		size = n0;
		v.resize(2 * n0, INF);
		for (int i = 0; i < w.size(); i++) v[i + size] = w[i];
		for (int i = n0 - 1; i >= 1; i--) v[i] = v[2 * i + 0] + v[2 * i + 1];
	}
	void add(int pos, ll x) {
		pos += size;
		v[pos] += x;
		while (pos > 1) {
			pos /= 2;
			v[pos] = v[pos * 2 + 0] + v[pos * 2 + 1];
		}
	}
	void set(int pos, ll x) {
		pos += size;
		v[pos] = x;
		while (pos > 1) {
			pos /= 2;
			v[pos] = v[pos * 2 + 0] + v[pos * 2 + 1];
		}
	}
	int query(int l, int r) const {
		l += size; r += size;
		int res = 0;
		while (l != r) {
			if (l & 1) res += v[l++];
			if (r & 1) res += v[--r];
			l /= 2; r /= 2;
		}
		return res;
	}
};


int main() {
	string s;
	ll k;
	cin >> s >> k;
	vector<set<ll>> alp(26);
	vector<ll> mi(26, 0);
	set<ll> us;
	map<ll, ll> m;
	vector<ll> w(26, 0);
	segment_tree seg(w);
	rep(i, 0, s.size()) {
		ll x = s[i] - 'a';
		if (x == 25) m[i] = 0;
		else m[i] = seg.query(x+1, 26);
		seg.add(x, 1);
		alp[x].insert(i);
	}
	string t = "";
	rep(j, 0, s.size()) {
		if (k == 0) break;
		rep(i, 0, 26) {
			char c = 'a' + i;
			bool ok = false;
			for (auto z : alp[i]) {
				if (m[z]-mi[i] <= k) {
					k -= m[z];
					t += c;
					us.insert(z);
					alp[i].erase(z);
					ok = true;
					break;
				}
				else { mi[i]++; break; }
			}
			if (ok) break;
		}
	}
	rep(i, 0, s.size()) {
		if (us.count(i)) continue;
		else t += s[i];
	}
	cout << t << endl;
}
accuracy: 1
time_ms: 330
memory_kb: 25680
final_rank: 19

code_snippet: //
#include<iostream>
#include<string>
#include<queue>
#include<vector>
#include<cassert>
#include<random>
#include<set>
#include<map>
#include<cassert>
#include<unordered_map>
#include<bitset>
#include<algorithm>
using namespace std;
using ll = long long;
const int inf=1<<30;
const ll INF=1LL<<62;
using P=pair<int,int>;
using PP=pair<ll,P>; 


using Type=ll;

Type op(Type x, Type y){
    //(x,y)を比較する任意の演算子.今回はmaxとした
    return (x+y);
}

Type e(){
    //initialize value
    return 0;
}


template<class Type,
    Type (*op)(Type,Type),
    Type (*e)()
    > class segment_tree{
    
    public:
        
        std::vector<Type> dat;
        int n=1;
        segment_tree(int n_){    
            while(n < n_){
                n*=2;
            }
            dat = std::vector<Type>(2*n-1,e());// 0,1,2,...,2*n-1,2*n-2
        }

        ~segment_tree(){
            std::vector<Type>().swap(dat);
        }

        void set(int k,Type a){
            update(k,a);
        }


        void update(int k,Type a){
            k+=n-1;
            dat[k] = a;
            while(k>0){
                k = (k-1)/2;
                dat[k]=op(dat[2*k+1],dat[2*k+2]);
            }
        }

        //[a,b)
        Type query(int a,int b,int k,int l,int r){
            if(r<=a || b<=l) return e();
            if(a<=l && r<=b) return dat[k];
            else{

                Type vl = query(a,b,2*k+1,l,(l+r)/2);
                Type vr = query(a,b,2*k+2,(l+r)/2,r);
                return op(vl,vr);
            }
        }

        //[a,b)の範囲でのmax
        Type query(int a,int b){
            return query(a,b,0,0,n);
        }

        Type operator[](int index){
            
            return get(index);
        }

        Type get(int index){
            index += n-1;
            return dat[index];
        }

        void add(int index,Type val){
            update(index,op(get(index),val));
        }
};
int main(){
    string s;
    cin>>s;
    ll K;
    cin>>K;
    int N=s.size();
    vector<int> p(N);
    const int M=26;


    segment_tree<Type,op,e> seg(N+5);
    
    vector<set<int>> pos(M);

    for(int i=0;i<N;i++){
        p[i]=s[i]-'a';
        pos[p[i]].insert(i);
    }

   
    vector<char> ans;

    for(int i=0;i<N;i++){
        for(char c=0;c<M;c++){
            if(pos[c].empty())continue;
            int index=*pos[c].begin();

            //[0,index)にあるcの数
            int flg=index - seg.query(0,index);

            if(flg>K)continue;
            K-=flg;
            ans.push_back('a'+c);
            pos[c].erase(index);
            seg.add(index,1);
            break;
        }
    }

    for(int i=0;i<N;i++){
        cout<<ans[i];
    }
    cout<<endl;




}
accuracy: 1
time_ms: 180
memory_kb: 17688
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct SegmentTree {
  vector<int> s; int seg_len;

  SegmentTree(int n) {
    seg_len = n;
    while (__builtin_popcount(seg_len) != 1) seg_len++;
    s.reserve(2 * seg_len);
  }

  void insert(int i) {
    int pos = i + seg_len;
    while (pos >= 1) s[pos] += 1, pos /= 2;
  }

  int num_earlier(int i) {
    int res = 0, l = seg_len, r = i + seg_len;
    while (l < r) {
      if (l % 2 == 1) res += s[l], l++;
      if (r % 2 == 1) res += s[r - 1], r--;
      l /= 2, r /=2;
    }
    return res;
  }
};

int main() {
  string s; cin >> s;
  int k; cin >> k;
  
  unordered_map<char,queue<int>> index;
  for (int i = 0; i < s.size(); i++) index[s[i]].push(i);
  
  SegmentTree st(s.size());
  for (int i = 0; i < s.size(); i++) {
    for (int j = 0; j < 26; j++) {
      char c = j + 'a';
      if (index[c].empty()) continue;
      int idx = index[c].front();
      int swaps = idx - st.num_earlier(idx);
      if (swaps <= k) {
        k -= swaps;
        st.insert(idx);
        index[c].pop();
        cout << c;
        break;
      } 
    }
  }
  cout << endl;
}
accuracy: 1
time_ms: 140
memory_kb: 5840
final_rank: 10