Submission #200862

#TimeUsernameProblemLanguageResultExecution timeMemory
200862EntityITCake 3 (JOI19_cake3)C++14
100 / 100
709 ms10476 KiB
#include<bits/stdc++.h>

using namespace std;

#define all(x) (x).begin(), (x).end()
#define sz(x) ( (int)(x).size() )
using LL = long long;

template<class T>
inline bool asMn(T &a, const T &b) { return a > b ? a = b, true : false; }
template<class T>
inline bool asMx(T &a, const T &b) { return a < b ? a = b, true : false; }

const LL infLL = 1e18;
mt19937 rng( (uint32_t)chrono::steady_clock::now().time_since_epoch().count() );

template<class T>
struct Bit {
  vector<T> a;
  Bit(int nNode = 0) { a.assign(nNode, T() ); }
  void reset(int nNode = 0) { a.assign(nNode, T() ); }

  void upd(int pos, int val) {
    for (int i = pos; i < sz(a); i |= i + 1) a[i] += val;
  }
  T get(int pos) {
    T ret = 0;
    for (int i = pos; i >= 0; i = (i & (i + 1) ) - 1) ret += a[i];
    return ret;
  }
  int findPos(int val) {
    int ret = 0;
    for (int i = __lg(sz(a) ); i >= 0; --i) {
      ret ^= 1 << i;
      if (ret < sz(a) && a[ret - 1] <= val) val -= a[ret - 1];
      else ret ^= 1 << i;
    }
    return ret;
  }
};
Bit<int> cnt;
Bit<LL> sum;

int n, m;
vector<pair<int, int> > piece;
vector<int> lable;

int l = 1, r = 0;
LL get(int Left, int Right) {
  while (r < Right) cnt.upd(lable[++r], 1), sum.upd(lable[r], piece[r].second);
  while (l > Left) cnt.upd(lable[--l], 1), sum.upd(lable[l], piece[l].second);
  while (r > Right) cnt.upd(lable[r], -1), sum.upd(lable[r], -piece[r].second), --r;
  while (l < Left) cnt.upd(lable[l], -1), sum.upd(lable[l], -piece[l].second), ++l;

  return sum.get(cnt.findPos(m - 1) );
}

LL ans = -infLL;
void solve(int Left, int Right, int bestL, int bestR) {
  int Mid = (Left + Right) >> 1;

  LL ret = -infLL;
  int bestM = bestL;
  for (int i = bestL; i <= min(bestR, Mid - m - 1); ++i) {
    LL tmp = get(i + 1, Mid - 1) + piece[i].second + piece[Mid].second - ( (piece[Mid].first - piece[i].first) << 1);
    if (tmp > ret) {
      ret = tmp;
      bestM = i;
    }
  }
  asMx(ans, ret);

  if (Left < Mid) solve(Left, Mid - 1, bestL, bestM);
  if (Mid < Right) solve(Mid + 1, Right, bestM, bestR);
}

int main() {
  ios_base::sync_with_stdio(0); cin.tie(0);

  #ifdef FourLeafClover
  freopen("input", "r", stdin);
  #endif // FourLeafCLover

  cin >> n >> m; m -= 2;

  piece.assign(n, {} );
  for (int i = 0; i < n; ++i) cin >> piece[i].second >> piece[i].first;
  sort(all(piece) );

  vector<pair<int, int> > com;
  for (int i = 0; i < n; ++i) com.emplace_back(piece[i].second, i);
  sort(all(com) );
  lable.assign(n, 0);
  for (int i = 0; i < n; ++i) lable[i] = n - 1 - (int)(lower_bound(all(com), make_pair(piece[i].second, i) ) - com.begin() );

  cnt.reset(n);
  sum.reset(n);
  solve(0, n - 1, 0, n - 1);

  cout << ans << '\n';

  return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...