Problem p00360 (C++) — buggy submission, verdict: Runtime Error

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

typedef long long ll;
typedef pair<int, int> P;

const int N = 1 << 18;
const ll INF = INT_MAX;

/*datのサイズはNに固定*/

class RMQ {
public:
  ll n;
  P dat[2 * N - 1];

  // 初期化
  RMQ() {
    n = N;
    for (int i = 0; i < 2 * n - 1; i++)
      dat[i] = P(INF, INF);
  }

  // k番目の値をaに変更
  void update(int k, P a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  //[a,b)の最小値を求める query(a,b,0,0,n)
  P query(int a, int b, int k = 0, int l = 0, int r = N) {
    if (r <= a || b <= l)
      return P(INF, INF);
    if (a <= l && r <= b)
      return dat[k];
    P vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    P vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return min(vl, vr);
  }
};

const int MAX_N = 1 << 18;

class BIT {
public:
  int n;
  ll bit0[MAX_N + 1], bit1[MAX_N + 1]; // 1オリジン
  BIT() {
    n = MAX_N;
    memset(bit0, 0, sizeof(bit0));
    memset(bit1, 0, sizeof(bit1));
  }
  BIT(int n) {
    this->n = n;
    memset(bit0, 0, sizeof(bit0));
    memset(bit1, 0, sizeof(bit1));
  }

  ll sum(ll *b, int i) {
    ll s = 0;
    while (i > 0) {
      s = (s + b[i]);
      i -= i & -i;
    }
    return s;
  }

  void add(ll *b, int i, ll v) {
    while (i <= n) {
      b[i] = (b[i] + v);
      i += i & -i;
    }
  }

  //[a,b]にxを加算(1<=a)
  void add(int a, int b, ll x) {
    add(bit0, a, -x * (a - 1));
    add(bit1, a, x);
    add(bit0, b + 1, x * b);
    add(bit1, b + 1, -x);
  }

  //[a,b]のsumを得る(1<=a)
  ll sum(int a, int b) {
    ll res = 0;
    res += sum(bit0, b) + sum(bit1, b) * b;
    res -= sum(bit0, a - 1) + sum(bit1, a - 1) * (a - 1);
    return res;
  }
};

string s;
int k;

void solve() {

  RMQ rmq = RMQ();
  BIT bit = BIT(s.size());

  for (int i = 0; i < s.size(); i++) {
    rmq.update(i, P(s[i], i));
    bit.add(i + 1, i + 1, 1);
  }

  string ans;

  while (ans.size() != s.size()) {

    int l = 0, r = s.size();

    while (l < r) {

      int m = (l + r) / 2;

      if (bit.sum(1, m + 1) <= k + 1)
        l = m + 1;
      else
        r = m;
    }

    P minp = rmq.query(0, l);
    char minc = minp.first;
    int minidx = minp.second;

    k -= bit.sum(1, minidx);
    bit.add(minidx + 1, minidx + 1, -1);
    rmq.update(minidx, P(INF, INF));

    ans += minc;
  }

  cout << ans << endl;
}

int main() {

  cin >> s;
  cin >> k;

  solve();

  return 0;
}


Error: 0

Fixed submission:

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

typedef long long ll;
typedef pair<int, int> P;

const int N = 1 << 17;
const ll INF = INT_MAX;

/*datのサイズはNに固定*/

class RMQ {
public:
  ll n;
  P dat[2 * N - 1];

  // 初期化
  RMQ() {
    n = N;
    for (int i = 0; i < 2 * n - 1; i++)
      dat[i] = P(INF, INF);
  }

  // k番目の値をaに変更
  void update(int k, P a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  //[a,b)の最小値を求める query(a,b,0,0,n)
  P query(int a, int b, int k = 0, int l = 0, int r = N) {
    if (r <= a || b <= l)
      return P(INF, INF);
    if (a <= l && r <= b)
      return dat[k];
    P vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    P vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return min(vl, vr);
  }
};

const int MAX_N = 1 << 17;

class BIT {
public:
  int n;
  ll bit0[MAX_N + 1], bit1[MAX_N + 1]; // 1オリジン
  BIT() {
    n = MAX_N;
    memset(bit0, 0, sizeof(bit0));
    memset(bit1, 0, sizeof(bit1));
  }
  BIT(int n) {
    this->n = n;
    memset(bit0, 0, sizeof(bit0));
    memset(bit1, 0, sizeof(bit1));
  }

  ll sum(ll *b, int i) {
    ll s = 0;
    while (i > 0) {
      s = (s + b[i]);
      i -= i & -i;
    }
    return s;
  }

  void add(ll *b, int i, ll v) {
    while (i <= n) {
      b[i] = (b[i] + v);
      i += i & -i;
    }
  }

  //[a,b]にxを加算(1<=a)
  void add(int a, int b, ll x) {
    add(bit0, a, -x * (a - 1));
    add(bit1, a, x);
    add(bit0, b + 1, x * b);
    add(bit1, b + 1, -x);
  }

  //[a,b]のsumを得る(1<=a)
  ll sum(int a, int b) {
    ll res = 0;
    res += sum(bit0, b) + sum(bit1, b) * b;
    res -= sum(bit0, a - 1) + sum(bit1, a - 1) * (a - 1);
    return res;
  }
};

string s;
int k;

void solve() {

  RMQ rmq = RMQ();
  BIT bit = BIT(s.size());

  for (int i = 0; i < s.size(); i++) {
    rmq.update(i, P(s[i], i));
    bit.add(i + 1, i + 1, 1);
  }

  string ans;

  while (ans.size() != s.size()) {

    int l = 0, r = s.size();

    while (l < r) {

      int m = (l + r) / 2;

      if (bit.sum(1, m + 1) <= k + 1)
        l = m + 1;
      else
        r = m;
    }

    P minp = rmq.query(0, l);
    char minc = minp.first;
    int minidx = minp.second;

    k -= bit.sum(1, minidx);
    bit.add(minidx + 1, minidx + 1, -1);
    rmq.update(minidx, P(INF, INF));

    ans += minc;
  }

  cout << ans << endl;
}

int main() {

  cin >> s;
  cin >> k;

  solve();

  return 0;
}