Problem p03078 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
struct edge {
  int to;     // 辺の行き先
  int weight; // 辺の重み
  edge(int t, int w) : to(t), weight(w){};
};
using Graph = vector<vector<int>>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define brep(n) for (int bit = 0; bit < (1 << n); bit++)
#define erep(i, container) for (auto i : container)
#define irep(i, n) for (int i = n - 1; i >= (int)0; i--)
#define rrep(i, m, n) for (int i = m; i < (int)(n); i++)
#define reprep(i, j, h, w) rep(i, h) rep(j, w)
#define all(x) (x).begin(), (x).end()
#define aall(x, n) (x).begin(), (x).begin() + (n)
#define VEC(type, name, n)                                                     \
  std::vector<type> name(n);                                                   \
  rep(i, n) std::cin >> name[i];
#define pb push_back
#define pf push_front
#define lb lower_bound
#define ub upper_bound
#define res resize
#define as assign
#define fi first
#define se second
#define itn int
#define mp make_pair
#define sum accumulate
#define keta fixed << setprecision
#define vvector(name, typ, m, n, a)                                            \
  vector<vector<typ>> name(m, vector<typ>(n, a))
#define vvvector(name, t, l, m, n, a)                                          \
  vector<vector<vector<t>>> name(l, vector<vector<t>>(m, vector<t>(n, a)));
#define vvvvector(name, t, k, l, m, n, a)                                      \
  vector<vector<vector<vector<t>>>> name(                                      \
      k, vector<vector<vector<t>>>(l, vector<vector<t>>(m, vector<t>(n, a))));

typedef long long ll;
const int INF = 2000000000;
const ll INF64 = 9223372036854775806ll;
const int mod = 1000000007ll;
const ll MOD = 1000000007LL;
//-0.4620981203755741
std::vector<ll> aa;
ll x, y, z;
bool cn(const std::vector<ll> &c, ll k,
        ll mi) { // 下のルーチンと併せてめぐる式二分探索
  int cnt = 0;
  rep(i, z) { cnt += int(aa.size() - (ub(all(aa), mi - c[i]) - aa.begin())); }
  //  std::cout << cnt << std::endl;
  if (cnt <= k)
    return false;
  else
    return true;
}
// 汎用的な二分探索のテンプレ
ll binary_search(const std::vector<ll> &c, ll key) {
  ll ng = -1; // 「index = 0」が条件を満たすこともあるので、初期値は -1
  ll ok =
      INF64; // 「index = a.size()-1」が条件を満たさないこともあるので、初期値は
             // a.size()
  /* ok と ng のどちらが大きいかわからないことを考慮 */
  while (abs(ok - ng) > 1) {
    ll mid = (ok + ng) / 2;

    if (cn(c, key, mid))
      ok = mid;
    else
      ng = mid;
  }
  return ok;
}

int main() {
  ll k;
  std::cin >> x >> y >> z >> k;
  VEC(ll, a, x);
  VEC(ll, b, y);
  VEC(ll, c, z);

  rep(i, x) rep(j, y) { aa.pb(a[i] + b[j]); }
  sort(all(aa));
  ll in = binary_search(c, k);
  // std::cout << in << std::endl;
  // std::cout << 123 << std::endl;
  std::vector<ll> ans;
  sort(all(aa), greater<ll>());
  rep(i, z) {
    rep(j, aa.size()) {
      if (c[i] + aa[j] >= in)
        ans.pb(c[i] + aa[j]);
      else
        break;
    }
  }
  //  std::cout << ans.size() << std::endl;
  sort(all(ans), greater<ll>());

  rep(i, k) { std::cout << ans[i] << std::endl; }
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
struct edge {
  int to;     // 辺の行き先
  int weight; // 辺の重み
  edge(int t, int w) : to(t), weight(w){};
};
using Graph = vector<vector<int>>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define brep(n) for (int bit = 0; bit < (1 << n); bit++)
#define erep(i, container) for (auto i : container)
#define irep(i, n) for (int i = n - 1; i >= (int)0; i--)
#define rrep(i, m, n) for (int i = m; i < (int)(n); i++)
#define reprep(i, j, h, w) rep(i, h) rep(j, w)
#define all(x) (x).begin(), (x).end()
#define aall(x, n) (x).begin(), (x).begin() + (n)
#define VEC(type, name, n)                                                     \
  std::vector<type> name(n);                                                   \
  rep(i, n) std::cin >> name[i];
#define pb push_back
#define pf push_front
#define lb lower_bound
#define ub upper_bound
#define res resize
#define as assign
#define fi first
#define se second
#define itn int
#define mp make_pair
#define sum accumulate
#define keta fixed << setprecision
#define vvector(name, typ, m, n, a)                                            \
  vector<vector<typ>> name(m, vector<typ>(n, a))
#define vvvector(name, t, l, m, n, a)                                          \
  vector<vector<vector<t>>> name(l, vector<vector<t>>(m, vector<t>(n, a)));
#define vvvvector(name, t, k, l, m, n, a)                                      \
  vector<vector<vector<vector<t>>>> name(                                      \
      k, vector<vector<vector<t>>>(l, vector<vector<t>>(m, vector<t>(n, a))));

typedef long long ll;
const int INF = 2000000000;
const ll INF64 = 9223372036854775806ll;
const int mod = 1000000007ll;
const ll MOD = 1000000007LL;
//-0.4620981203755741
std::vector<ll> aa;
ll x, y, z;
bool cn(const std::vector<ll> &c, ll k,
        ll mi) { // 下のルーチンと併せてめぐる式二分探索
  int cnt = 0;
  rep(i, z) { cnt += int(aa.size() - (ub(all(aa), mi - c[i]) - aa.begin())); }
  // std::cout << cnt << std::endl;
  if (cnt < k)
    return false;
  else
    return true;
}
// 汎用的な二分探索のテンプレ
ll binary_search(const std::vector<ll> &c, ll key) {
  ll ng = -1; // 「index = 0」が条件を満たすこともあるので、初期値は -1
  ll ok =
      INF64; // 「index = a.size()-1」が条件を満たさないこともあるので、初期値は
             // a.size()
  /* ok と ng のどちらが大きいかわからないことを考慮 */
  while (abs(ok - ng) > 1) {
    ll mid = (ok + ng) / 2;

    if (cn(c, key, mid))
      ok = mid;
    else
      ng = mid;
  }
  return ok;
}

int main() {
  ll k;
  std::cin >> x >> y >> z >> k;
  VEC(ll, a, x);
  VEC(ll, b, y);
  VEC(ll, c, z);

  rep(i, x) rep(j, y) { aa.pb(a[i] + b[j]); }
  sort(all(aa));
  ll in = binary_search(c, k);
  // std::cout << in << std::endl;
  // std::cout << 123 << std::endl;
  std::vector<ll> ans;
  sort(all(aa), greater<ll>());
  rep(i, z) {
    rep(j, aa.size()) {
      if (c[i] + aa[j] >= in)
        ans.pb(c[i] + aa[j]);
      else
        break;
    }
  }
  //  std::cout << ans.size() << std::endl;
  sort(all(ans), greater<ll>());

  rep(i, k) { std::cout << ans[i] << std::endl; }
}