1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| #include <cstdio> #include <vector> #include <algorithm> using std::sort; using std::min; using std::max; using std::vector; typedef long long ll; const int N = 2e5 + 5; const int K = N / 2; vector <ll> a[N]; ll check(vector <ll> &a, vector <ll> &b, int ia, int ib) { if (a[ia] == -1 || b[ib] == -1) return -1ll; else return a[ia] + b[ib]; } ll find_ans(vector <ll> &odd_l, vector <ll> &odd_r, vector <ll> &even_l, vector <ll> &even_r, int L, int R, int x) { ll tmp = -1; int l = (L & 1) ? L + 1 : L, r = (R & 1) ? R - 1 : R; ll lchk, rchk; l = (l - 2) / 2, r = (r - 2) / 2; if (l <= r) { while (l < r) { int lmid = l + (r - l) / 3, rmid = r - (r - l) / 3; if (x & 1) lchk = check(even_l, odd_r, lmid, (x - lmid * 2 - 2 - 3) / 2); else lchk = check(even_l, even_r, lmid, (x - lmid * 2 - 2 - 2) / 2); if (x & 1) rchk = check(even_l, odd_r, rmid, (x - rmid * 2 - 2 - 3) / 2); else rchk = check(even_l, even_r, rmid, (x - rmid * 2 - 2 - 2) / 2); if (lchk > rchk) r = rmid - 1; else l = lmid + 1; } if (x & 1) lchk = check(even_l, odd_r, l, (x - l * 2 - 2 - 3) / 2); else lchk = check(even_l, even_r, l, (x - l * 2 - 2 - 2) / 2); if (x & 1) rchk = check(even_l, odd_r, r, (x - r * 2 - 2 - 3) / 2); else rchk = check(even_l, even_r, r, (x - r * 2 - 2 - 2) / 2); tmp = max(tmp, max(lchk, rchk)); } l = (L & 1) ? L : L + 1, r = (R & 1) ? R : R - 1; l = (l - 3) / 2, r = (r - 3) / 2; if (l <= r) { while (l < r) { int lmid = l + (r - l) / 3, rmid = r - (r - l) / 3; if (x & 1) lchk = check(odd_l, even_r, lmid, (x - lmid * 2 - 3 - 2) / 2); else lchk = check(odd_l, odd_r, lmid, (x - lmid * 2 - 3 - 3) / 2); if (x & 1) rchk = check(odd_l, even_r, rmid, (x - rmid * 2 - 3 - 2) / 2); else rchk = check(odd_l, odd_r, rmid, (x - rmid * 2 - 3 - 3) / 2); if (lchk > rchk) r = rmid - 1; else l = lmid + 1; } if (x & 1) lchk = check(odd_l, even_r, l, (x - l * 2 - 3 - 2) / 2); else lchk = check(odd_l, odd_r, l, (x - l * 2 - 3 - 3) / 2); if (x & 1) rchk = check(odd_l, even_r, r, (x - r * 2 - 3 - 2) / 2); else rchk = check(odd_l, odd_r, r, (x - r * 2 - 3 - 3) / 2); tmp = max(tmp, max(lchk, rchk)); } return tmp; } vector <ll> merge(vector <ll> &lans, vector <ll> &rans) { int lsz = lans.size(), rsz = rans.size(); int sz = lsz + rsz; vector <ll> ans(sz); ans[0] = -1; ans[1] = max(lsz >= 2 ? lans[1] : -1, rsz >= 2 ? rans[1] : -1); ans[2] = max(lsz >= 3 ? lans[2] : -1, rsz >= 3 ? rans[2] : -1); vector <ll> tmp_even_l, tmp_even_r, tmp_odd_l, tmp_odd_r; for (int i = 1; i < lsz; ++i) { if (i & 1) tmp_even_l.push_back(lans[i]); else tmp_odd_l.push_back(lans[i]); } for (int i = 1; i < rsz; ++i) { if (i & 1) tmp_even_r.push_back(rans[i]); else tmp_odd_r.push_back(rans[i]); } for (int i = 4; i <= sz; ++i) { auto tmp = max(lsz >= i ? lans[i - 1] : -1, rsz >= i ? rans[i - 1] : -1); int L = max(2, i - rsz), R = min(i - 2, lsz); tmp = max(tmp, find_ans(tmp_odd_l, tmp_odd_r, tmp_even_l, tmp_even_r, L, R, i)); ans[i - 1] = tmp; } return ans; } vector <ll> query(int l, int r) { if (l == r) { if (a[l].size() == 0) a[l].push_back(-1); a[l][0] = -1; return a[l]; } int mid = (l + r) >> 1; auto lans = query(l, mid), rans = query(mid + 1, r); return merge(lans, rans); } int main() { int n, k; scanf("%d%d", &n, &k); for (int i = 1; i <= n; ++i) { int x, y; scanf("%d%d", &x, &y); a[x].push_back(y); } auto cmp = [&](int x, int y) { return x > y; }; for (int i = 1; i <= k; ++i) { if (a[i].size() > 0) { sort(a[i].begin(), a[i].end(), cmp); } for (int j = 1; j < a[i].size(); ++j) { a[i][j] += a[i][j - 1]; } } auto ans = query(1, k); for (auto x : ans) { printf("%lld\n", x); } return 0; }
|