Submission #807700

#TimeUsernameProblemLanguageResultExecution timeMemory
807700dong_liuCake 3 (JOI19_cake3)C++17
100 / 100
700 ms9536 KiB
#include <bits/stdc++.h>
using namespace std;

#define N 200000

namespace kactl {

typedef long long ll;
#define sz(x) int(x.size())

/**
 * Author: Lukas Polacek
 * Date: 2009-10-30
 * License: CC0
 * Source: folklore/TopCoder
 * Description: Computes partial sums a[0] + a[1] + ... + a[pos - 1], and
 * updates single elements a[i], taking the difference between the old and new
 * value. Time: Both operations are $O(\log N)$. Status: Stress-tested
 */

struct FT {
  vector<ll> s;
  vector<int> k;
  void init(int n) {
    s.assign(n, 0);
    k.assign(n, 0);
  }
  void update(int pos, ll dif, int c) {  // a[pos] += dif
    for (; pos < sz(s); pos |= pos + 1) {
      s[pos] += dif;
      k[pos] += c;
    }
  }
  ll query(int pos) {  // sum of values in [0, pos)
    ll res = 0;
    for (; pos > 0; pos &= pos - 1) res += s[pos - 1];
    return res;
  }
  int lower_bound(int c) {  // min pos st sum of [0, pos] >= sum
    // Returns n if no sum is >= sum, or -1 if empty sum is.
    if (c <= 0) return -1;
    int pos = 0;  // ll sum = 0;
    for (int pw = 1 << 25; pw; pw >>= 1) {
      if (pos + pw <= sz(k) && k[pos + pw - 1] < c) {
        pos += pw, c -= k[pos - 1];
      }
    }
    return pos;
  }
  ll q_(int c) { return query(lower_bound(c) + 1); }
} ft;

}  // namespace kactl

array<int, 2> aa[N];
int ii[N];

int l_ = 0, r_ = -1, m_;

long long query(int l, int r) {
  if (r - l + 1 < m_) return -0x3f3f3f3f3f3f3f3f;
  while (l_ < l) kactl::ft.update(ii[l_], -aa[l_][1], -1), l_++;
  while (l_ > l) l_--, kactl::ft.update(ii[l_], +aa[l_][1], +1);
  while (r_ > r) kactl::ft.update(ii[r_], -aa[r_][1], -1), r_--;
  while (r_ < r) r_++, kactl::ft.update(ii[r_], +aa[r_][1], +1);
  return kactl::ft.q_(m_) - (long long)2 * (aa[r][0] - aa[l][0]);
}

long long ans = -0x3f3f3f3f3f3f3f3f;

void dnc(int lo, int ro, int l, int r) {
  long long tmp;
  int m, mo;

  if (l > r) return;
  m = (l + r) / 2, mo = lo;
  tmp = query(mo, m);
  for (int i = lo; i <= ro; i++) {
    long long tmp_ = query(i, m);

    if (tmp_ > tmp) {
      tmp = tmp_;
      mo = i;
    }
  }
  ans = max(ans, tmp);
  if (mo == -1) {
    assert(0);
    dnc(lo, ro, m + 1, r);
  } else {
    dnc(lo, mo, l, m - 1);
    dnc(mo, ro, m + 1, r);
  }
}

int main() {
  static int ii_[N];
  int n;

  scanf("%d%d", &n, &m_);
  for (int i = 0; i < n; i++) {
    scanf("%d%d", &aa[i][1], &aa[i][0]);
    ii_[i] = i;
  }
  sort(aa, aa + n);
  sort(ii_, ii_ + n, [&](int i, int j) { return aa[i][1] > aa[j][1]; });
  for (int i = 0; i < n; i++) ii[ii_[i]] = i;
  kactl::ft.init(n + 5);
  dnc(0, n - 1, 0, n - 1);
  printf("%lld\n", ans);
  return 0;
}

Compilation message (stderr)

cake3.cpp: In function 'int main()':
cake3.cpp:100:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  100 |   scanf("%d%d", &n, &m_);
      |   ~~~~~^~~~~~~~~~~~~~~~~
cake3.cpp:102:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  102 |     scanf("%d%d", &aa[i][1], &aa[i][0]);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...