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

// セグ木基本
#include "bits/stdc++.h"
using namespace std;
#define REP(i, n) for (ll i = 0; i < n; i++)
#define ll long long
#define MOD 1000000007LL
#define llMAX 9223372036854775807LL
#define llMIN -9223372036854775807LL
using vi = vector<ll>;
using vvi = vector<vi>;

ll n;

class SegTree {
public:
  ll n2, ln2;      // 2のべき乗になる数でn以上の数//n2のlog2値
  vector<ll> data; // ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
  vector<int> indexdata;
  SegTree() {}
  void Init(ll inn) {
    ln2 = ceil(log2(inn));
    n2 = 1 << ln2;
    data.resize(n2 * 2);
    indexdata.resize(n2 * 2);
    for (ll i = 0; i < n2 * 2; i++)
      data[i] = Initval(); // ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
    for (int i = 0; i < n2; i++)
      indexdata[i + n2] = i;
  }
  // 配列内初期化●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
  ll Initval() { return llMIN; }
  // min関数的な
  // ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
  ll SGTfunc(ll d0, ll d1) { return max(d0, d1); }
  // データをセットして内部更新 O(logn)
  void Updata(ll posi, ll d) {
    ll myi = posi + n2;
    data[myi] = d;                 // 葉
    for (ll i = 0; i < ln2; i++) { // 中間要素
      myi /= 2;
      data[myi] = SGTfunc(data[myi * 2], data[myi * 2 + 1]);
      if (data[myi * 2] == data[myi]) {
        indexdata[myi] = indexdata[myi * 2];
      } else {
        indexdata[myi] = indexdata[myi * 2 + 1];
      }
    }
  }
  void Delete(ll posi) // 1要素削除して初期化
  {
    Updata(posi, Initval());
  }

  // lを含むrを含まないところまでの区間
  ll GetMin(ll l, ll r) {
    ll ret = data[l];
    ll l_ = l;
    ll r_ = r;
    for (ll i = 0; (l_ + r_) > 0; i++) {
      ll offset = 1 << (ln2 - i);
      if (r_ % 2 == 1) {
        if (r_ - 1 >= l_) {
          ret = SGTfunc(ret, data[offset + r_ - 1]);
          r_--;
        }
      }
      if (l_ % 2 == 1) {
        if (l_ < r_) {
          ret = SGTfunc(ret, data[offset + l_]);
          l_++;
        }
      }
      r_ >>= 1;
      l_ >>= 1;
    }
    return ret;
  }
  ll GetAll() // 0～最後の要素まで
  {
    return GetMin(0, n2);
  }

  // lを含むrを含まないところまでの区間で_最小_の値をもつindexを返す
  int GetMinIndex(ll l, ll r) {
    int retindex = l;
    ll ret = data[l];
    ll l_ = l;
    ll r_ = r;
    for (ll i = 0; (l_ + r_) > 0; i++) {
      ll offset = 1 << (ln2 - i);
      if (r_ % 2 == 1) {
        if (r_ - 1 >= l_) {
          ll ret_tmp = SGTfunc(ret, data[offset + r_ - 1]);
          if (ret != ret_tmp) {
            retindex = indexdata[offset + r_ - 1];
            ret = ret_tmp;
          }
          r_--;
        }
      }
      if (l_ % 2 == 1) {
        if (l_ < r_) {
          ll ret_tmp = SGTfunc(ret, data[offset + l_]);
          if (ret != ret_tmp) {
            retindex = indexdata[offset + l_];
            ret = ret_tmp;
          }
          l_++;
        }
      }
      r_ >>= 1;
      l_ >>= 1;
    }
    return retindex;
  }
  int GetAllIndex() // 0～最後の要素まで
  {
    return GetMinIndex(0, n2);
  }
};

int main() {
  ll ans = 0;
  cin >> n;
  vi a(n);
  REP(i, n) cin >> a[i];

  sort(a.begin(), a.end(), greater<ll>());

  SegTree segtree;
  segtree.Init(n);

  if (n == 2) {
    cout << a[0] << endl;
    return 0;
  }

  ans += a[0];
  segtree.Updata(0, a[0] + a[1] * 1000000001LL);
  segtree.Updata(1, a[0] + a[1] * 1000000001LL);
  for (ll i = 2; i < n; i++) {
    ll val = segtree.GetAll();
    int idx = segtree.GetAllIndex();
    ll scoremin = val / 1000000001LL;
    ll scoremax = val % 1000000001LL;
    ans += scoremin;
    segtree.Updata(idx, a[i] * 1000000001LL + scoremin);
    segtree.Updata(i, a[i] * 1000000001LL + scoremax);
  }

  cout << ans << endl;
  return 0;
}

Error: -6
munmap_chunk(): invalid pointer


Fixed submission:

// セグ木基本
#include "bits/stdc++.h"
using namespace std;
#define REP(i, n) for (ll i = 0; i < n; i++)
#define ll long long
#define MOD 1000000007LL
#define llMAX 9223372036854775807LL
#define llMIN -9223372036854775807LL
using vi = vector<ll>;
using vvi = vector<vi>;

ll n;

class SegTree {
public:
  ll n2, ln2;      // 2のべき乗になる数でn以上の数//n2のlog2値
  vector<ll> data; // ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
  vector<int> indexdata;
  SegTree() {}
  void Init(ll inn) {
    ln2 = ceil(log2(inn));
    n2 = 1 << ln2;
    data.resize(n2 * 2);
    indexdata.resize(n2 * 2);
    for (ll i = 0; i < n2 * 2; i++) {
      data[i] = Initval(); // ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
      indexdata[i] = (int)i;
    }
  }
  // 配列内初期化●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
  ll Initval() { return llMIN; }
  // min関数的な
  // ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
  ll SGTfunc(ll d0, ll d1) { return max(d0, d1); }
  // データをセットして内部更新 O(logn)
  void Updata(ll posi, ll d) {
    ll myi = posi + n2;
    data[myi] = d;                 // 葉
    for (ll i = 0; i < ln2; i++) { // 中間要素
      myi /= 2;
      data[myi] = SGTfunc(data[myi * 2], data[myi * 2 + 1]);
      if (data[myi * 2] == data[myi]) {
        indexdata[myi] = indexdata[myi * 2];
      } else {
        indexdata[myi] = indexdata[myi * 2 + 1];
      }
    }
  }
  void Delete(ll posi) // 1要素削除して初期化
  {
    Updata(posi, Initval());
  }

  // lを含むrを含まないところまでの区間
  ll GetMin(ll l, ll r) {
    ll ret = data[l];
    ll l_ = l;
    ll r_ = r;
    for (ll i = 0; (l_ + r_) > 0; i++) {
      ll offset = 1 << (ln2 - i);
      if (r_ % 2 == 1) {
        if (r_ - 1 >= l_) {
          ret = SGTfunc(ret, data[offset + r_ - 1]);
          r_--;
        }
      }
      if (l_ % 2 == 1) {
        if (l_ < r_) {
          ret = SGTfunc(ret, data[offset + l_]);
          l_++;
        }
      }
      r_ >>= 1;
      l_ >>= 1;
    }
    return ret;
  }
  ll GetAll() // 0～最後の要素まで
  {
    return GetMin(0, n2);
  }

  // lを含むrを含まないところまでの区間で_最小_の値をもつindexを返す
  int GetMinIndex(ll l, ll r) {
    int retindex = l;
    ll ret = data[l];
    ll l_ = l;
    ll r_ = r;
    for (ll i = 0; (l_ + r_) > 0; i++) {
      ll offset = 1 << (ln2 - i);
      if (r_ % 2 == 1) {
        if (r_ - 1 >= l_) {
          ll ret_tmp = SGTfunc(ret, data[offset + r_ - 1]);
          if (ret != ret_tmp) {
            retindex = indexdata[offset + r_ - 1];
            ret = ret_tmp;
          }
          r_--;
        }
      }
      if (l_ % 2 == 1) {
        if (l_ < r_) {
          ll ret_tmp = SGTfunc(ret, data[offset + l_]);
          if (ret != ret_tmp) {
            retindex = indexdata[offset + l_];
            ret = ret_tmp;
          }
          l_++;
        }
      }
      r_ >>= 1;
      l_ >>= 1;
    }
    return retindex;
  }
  int GetAllIndex() // 0～最後の要素まで
  {
    return GetMinIndex(0, n2);
  }
};

int main() {
  ll ans = 0;
  cin >> n;
  vi a(n);
  REP(i, n) cin >> a[i];

  sort(a.begin(), a.end(), greater<ll>());

  SegTree segtree;
  segtree.Init(n);

  if (n == 2) {
    cout << a[0] << endl;
    return 0;
  }

  ans += a[0];
  segtree.Updata(0, a[0] + a[1] * 1000000001LL);
  segtree.Updata(1, a[0] + a[1] * 1000000001LL);
  for (ll i = 2; i < n; i++) {
    ll val = segtree.GetAll();
    int idx = segtree.GetAllIndex();
    ll scoremin = val / 1000000001LL;
    ll scoremax = val % 1000000001LL;
    ans += scoremin;
    segtree.Updata(idx, a[i] * 1000000001LL + scoremin);
    segtree.Updata(i, a[i] * 1000000001LL + scoremax);
  }

  cout << ans << endl;
  return 0;
}