matistjati

Untitled

Jun 24th, 2026
8
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.09 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define rep(i, a, b) for(int i = a; i < (b); ++i)
  5. #define all(x) begin(x), end(x)
  6. #define sz(x) (int)(x).size()
  7. typedef long long ll;
  8. typedef pair<int, int> pii;
  9. typedef vector<int> vi;
  10.  
  11. #include <bits/extc++.h> /// include-line, keep-include
  12.  
  13. const ll INF = numeric_limits<ll>::max() / 4;
  14.  
  15. struct MCMF {
  16. struct edge {
  17. int from, to, rev;
  18. ll cap, cost, flow;
  19. };
  20. int N;
  21. vector<vector<edge>> ed;
  22. vi seen;
  23. vector<ll> dist, pi;
  24. vector<edge*> par;
  25.  
  26. MCMF(int N) : N(N), ed(N), seen(N), dist(N), pi(N), par(N) {}
  27.  
  28. void addEdge(int from, int to, ll cap, ll cost) {
  29. if (from == to) return;
  30. ed[from].push_back(edge{ from,to,sz(ed[to]),cap,cost,0 });
  31. ed[to].push_back(edge{ to,from,sz(ed[from])-1,0,-cost,0 });
  32. }
  33.  
  34. void path(int s) {
  35. fill(all(seen), 0);
  36. fill(all(dist), INF);
  37. dist[s] = 0; ll di;
  38.  
  39. __gnu_pbds::priority_queue<pair<ll, int>> q;
  40. vector<decltype(q)::point_iterator> its(N);
  41. q.push({ 0, s });
  42.  
  43. while (!q.empty()) {
  44. s = q.top().second; q.pop();
  45. seen[s] = 1; di = dist[s] + pi[s];
  46. for (edge& e : ed[s]) if (!seen[e.to]) {
  47. ll val = di - pi[e.to] + e.cost;
  48. if (e.cap - e.flow > 0 && val < dist[e.to]) {
  49. dist[e.to] = val;
  50. par[e.to] = &e;
  51. if (its[e.to] == q.end())
  52. its[e.to] = q.push({ -dist[e.to], e.to });
  53. else
  54. q.modify(its[e.to], { -dist[e.to], e.to });
  55. }
  56. }
  57. }
  58. rep(i,0,N) pi[i] = min(pi[i] + dist[i], INF);
  59. }
  60.  
  61. pair<ll, ll> maxflow(int s, int t) {
  62. ll totflow = 0, totcost = 0;
  63. while (path(s), seen[t]) {
  64. ll fl = INF;
  65. for (edge* x = par[t]; x; x = par[x->from])
  66. fl = min(fl, x->cap - x->flow);
  67.  
  68. totflow += fl;
  69. for (edge* x = par[t]; x; x = par[x->from]) {
  70. x->flow += fl;
  71. ed[x->to][x->rev].flow -= fl;
  72. }
  73. }
  74. rep(i,0,N) for(edge& e : ed[i]) totcost += e.cost * e.flow;
  75. return {totflow, totcost/2};
  76. }
  77.  
  78. // If some costs can be negative, call this before maxflow:
  79. void setpi(int s) { // (otherwise, leave this out)
  80. fill(all(pi), INF); pi[s] = 0;
  81. int it = N, ch = 1; ll v;
  82. while (ch-- && it--)
  83. rep(i,0,N) if (pi[i] != INF)
  84. for (edge& e : ed[i]) if (e.cap)
  85. if ((v = pi[i] + e.cost) < pi[e.to])
  86. pi[e.to] = v, ch = 1;
  87. assert(it >= 0); // negative cost cycle
  88. }
  89. };
  90.  
  91. int main() {
  92. cin.tie(0)->sync_with_stdio(0);
  93.  
  94. int n;
  95. cin >> n;
  96. vector<pii> ppl(n);
  97. rep(i, 0, n) cin >> ppl[i].first >> ppl[i].second;
  98.  
  99. int best = 0;
  100. rep(i, 0, n) if (ppl[i].first > ppl[best].first) best = i;
  101. rep(i, 0, n) if (i != best) ppl[i].second--;
  102. sort(all(ppl));
  103.  
  104. auto solve = [&](int mul) {
  105. int nodecnt = 2 * n + 2;
  106. MCMF flow(nodecnt);
  107. rep(i, 0, n) {
  108. if (i != n - 1) flow.addEdge(nodecnt - 2, i, 1, 0);
  109. flow.addEdge(i + n, nodecnt - 1, ppl[i].second, 0);
  110. rep(j, i + 1, n) {
  111. flow.addEdge(i, j + n, 1, (ppl[i].first ^ ppl[j].first) * mul);
  112. }
  113. }
  114. flow.setpi(nodecnt - 2);
  115. auto [_, cost] = flow.maxflow(nodecnt - 2, nodecnt - 1);
  116. return cost * mul;
  117. };
  118. cout << solve(1) << " " << solve(-1);
  119.  
  120. return 0;
  121. }
  122.  
Advertisement
Add Comment
Please, Sign In to add comment