Problem p03557 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <math.h>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stdio.h>
#include <string>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define POW(n) ((n) * (n))
#define ALL(a) (a).begin(), (a).end()

using namespace std;

namespace Dump {
#define dump(...) Dump::print(#__VA_ARGS__, __VA_ARGS__)
static std::vector<string> dumpKey;
static string dumpKeyBuf;

void print() { cerr << endl; }
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
  if (dumpKey.empty()) {
    dumpKeyBuf = head;
    dumpKeyBuf.erase(std::remove_if(dumpKeyBuf.begin(), dumpKeyBuf.end(),
                                    [](char c) { return c == ' '; }),
                     dumpKeyBuf.end());

    std::istringstream stream(dumpKeyBuf);
    string field;
    while (std::getline(stream, field, ','))
      dumpKey.push_back(field);

    reverse(dumpKey.begin(), dumpKey.end());
  } else {
    cerr << dumpKey.back() << ":" << head << "  ";
    dumpKey.pop_back();
  }
  Dump::print(std::move(tail)...);
}
} // namespace Dump

typedef long long ll;
typedef unsigned long long ull;

typedef vector<int> vi;
typedef vector<double> vd;
typedef vector<string> vs;
typedef vector<long long> vll;
typedef vector<unsigned long long> vull;
typedef pair<int, int> pii; // p.first p.second

// ll n = to_T<ll>("114514")
template <class T> T to_T(const string &s) {
  istringstream is(s);
  T res;
  is >> res;
  return res;
}
template <class T> string to_s(const T &a) {
  ostringstream os;
  os << a;
  return os.str();
}

// BinaryIndexSearch 1-indexd
class BIT {
public:
  vector<long long> bit;
  int M;

  BIT(int M) : bit(vector<long long>(M + 1, 0)), M(M) {}

  long long get(int i, bool first = true) const {
    if (first)
      assert(i > 0);
    if (!i)
      return 0;
    return bit[i] + get(i - (i & -i), false);
  }

  // i,i+1,i+2,...の区間にxを加算する
  void add(int i, long long x) {
    assert(i > 0);
    if (i > M)
      return;
    bit[i] += x;
    add(i + (i & -i), x);
  }
};

int binarySearch(std::vector<ll> &v, ll key) {
  int left = 0;
  int right = v.size() - 1;

  // 残り10以下になるまで探索
  while (right - left > 10) {
    int mid = (left + right) / 2;

    if (v[mid] < key) {
      left = mid;
    } else {
      right = mid;
    }
  }

  // あとは愚直に
  for (int i = left; i < v.size(); ++i) {
    if (v[i] > key) {
      return i;
    }
  }

  return v.size();
}

void solve(long long N, vector<long long> A, vector<long long> B,
           vector<long long> C) {
  sort(ALL(A));
  // REP(i, N) { cerr << A[i] << " "; }
  // cerr << endl;
  sort(ALL(B));
  // REP(i, N) { cerr << B[i] << " "; }
  // cerr << endl;
  sort(ALL(C));
  // REP(i, N) { cerr << C[i] << " "; }
  // cerr << endl;

  // 2 3 6 14 53 159
  // 6 9 58 79 84 323
  // 2 50 79 288 383 2643
  // 5 5 4 4 3 2

  vll BB(N);
  BIT bit(N + 10);
  REP(i, N) {
    ll index = B[i];
    BB[i] = N - binarySearch(C, B[i]);
    bit.add(i + 1, BB[i]);
    // dump(B[i], BB[i]);
  }
  // REP(i, N) { cerr << BB[i] << " "; }
  // cerr << endl;

  ll ans = 0;
  REP(i, N) {
    int mid_index = binarySearch(B, A[i]);
    // int mid = N - binarySearch(B, A[i]);
    // int last =
    // cerr << "-----------------" << endl;
    if (mid_index == 0) {
      ans += bit.get(N + 2);
      // dump(bit.get(N + 2));
    } else {
      ans += bit.get(N + 2) - bit.get(mid_index + 1 - 1);
      // dump(bit.get(N + 2) - bit.get(mid_index + 1 - 1));
    }
    // dump(A[i], mid_index);
  }

  cout << ans << endl;
}

int main() {
  ios::sync_with_stdio(false);
  long long N;
  cin >> N;
  vector<long long> A(N - 1 + 1);
  vector<long long> B(N - 1 + 1);
  vector<long long> C(N - 1 + 1);
  for (int i = 0; i <= N - 1; i++) {
    cin >> A[i];
  }
  for (int i = 0; i <= N - 1; i++) {
    cin >> B[i];
  }
  for (int i = 0; i <= N - 1; i++) {
    cin >> C[i];
  }
  solve(N, A, B, C);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <math.h>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stdio.h>
#include <string>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define POW(n) ((n) * (n))
#define ALL(a) (a).begin(), (a).end()

using namespace std;

namespace Dump {
#define dump(...) Dump::print(#__VA_ARGS__, __VA_ARGS__)
static std::vector<string> dumpKey;
static string dumpKeyBuf;

void print() { cerr << endl; }
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
  if (dumpKey.empty()) {
    dumpKeyBuf = head;
    dumpKeyBuf.erase(std::remove_if(dumpKeyBuf.begin(), dumpKeyBuf.end(),
                                    [](char c) { return c == ' '; }),
                     dumpKeyBuf.end());

    std::istringstream stream(dumpKeyBuf);
    string field;
    while (std::getline(stream, field, ','))
      dumpKey.push_back(field);

    reverse(dumpKey.begin(), dumpKey.end());
  } else {
    cerr << dumpKey.back() << ":" << head << "  ";
    dumpKey.pop_back();
  }
  Dump::print(std::move(tail)...);
}
} // namespace Dump

typedef long long ll;
typedef unsigned long long ull;

typedef vector<int> vi;
typedef vector<double> vd;
typedef vector<string> vs;
typedef vector<long long> vll;
typedef vector<unsigned long long> vull;
typedef pair<int, int> pii; // p.first p.second

// ll n = to_T<ll>("114514")
template <class T> T to_T(const string &s) {
  istringstream is(s);
  T res;
  is >> res;
  return res;
}
template <class T> string to_s(const T &a) {
  ostringstream os;
  os << a;
  return os.str();
}

// BinaryIndexSearch 1-indexd
class BIT {
public:
  vector<long long> bit;
  int M;

  BIT(int M) : bit(vector<long long>(M + 1, 0)), M(M) {}

  long long get(int i, bool first = true) const {
    if (first)
      assert(i > 0);
    if (!i)
      return 0;
    return bit[i] + get(i - (i & -i), false);
  }

  // i,i+1,i+2,...の区間にxを加算する
  void add(int i, long long x) {
    assert(i > 0);
    if (i > M)
      return;
    bit[i] += x;
    add(i + (i & -i), x);
  }
};

int binarySearch(std::vector<ll> &v, ll key) {
  int left = 0;
  int right = v.size() - 1;

  auto it = upper_bound(v.begin(), v.end(), key);
  return distance(v.begin(), it);

  // 残り10以下になるまで探索
  while (right - left > 10) {
    int mid = (left + right) / 2;

    if (v[mid] < key) {
      left = mid;
    } else {
      right = mid;
    }
  }

  // あとは愚直に
  for (int i = left; i < v.size(); ++i) {
    if (v[i] > key) {
      return i;
    }
  }

  return v.size();
}

void solve(long long N, vector<long long> A, vector<long long> B,
           vector<long long> C) {
  sort(ALL(A));
  // REP(i, N) { cerr << A[i] << " "; }
  // cerr << endl;
  sort(ALL(B));
  // REP(i, N) { cerr << B[i] << " "; }
  // cerr << endl;
  sort(ALL(C));
  // REP(i, N) { cerr << C[i] << " "; }
  // cerr << endl;

  // 2 3 6 14 53 159
  // 6 9 58 79 84 323
  // 2 50 79 288 383 2643
  // 5 5 4 4 3 2

  vll BB(N);
  BIT bit(N + 10);
  REP(i, N) {
    ll index = B[i];
    BB[i] = N - binarySearch(C, B[i]);
    bit.add(i + 1, BB[i]);
    // dump(B[i], BB[i]);
  }
  // REP(i, N) { cerr << BB[i] << " "; }
  // cerr << endl;

  ll ans = 0;
  REP(i, N) {
    int mid_index = binarySearch(B, A[i]);
    // int mid = N - binarySearch(B, A[i]);
    // int last =
    // cerr << "-----------------" << endl;
    if (mid_index == 0) {
      ans += bit.get(N + 2);
      // dump(bit.get(N + 2));
    } else {
      ans += bit.get(N + 2) - bit.get(mid_index + 1 - 1);
      // dump(bit.get(N + 2) - bit.get(mid_index + 1 - 1));
    }
    // dump(A[i], mid_index);
  }

  cout << ans << endl;
}

int main() {
  ios::sync_with_stdio(false);
  long long N;
  cin >> N;
  vector<long long> A(N - 1 + 1);
  vector<long long> B(N - 1 + 1);
  vector<long long> C(N - 1 + 1);
  for (int i = 0; i <= N - 1; i++) {
    cin >> A[i];
  }
  for (int i = 0; i <= N - 1; i++) {
    cin >> B[i];
  }
  for (int i = 0; i <= N - 1; i++) {
    cin >> C[i];
  }
  solve(N, A, B, C);
  return 0;
}