Submission #1175087

#TimeUsernameProblemLanguageResultExecution timeMemory
1175087zNatsumiHoliday (IOI14_holiday)C++20
100 / 100
435 ms5824 KiB
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 1e5 + 5;

int n, st, d, a[N], lim, Lb, Rb;
ll res = 0LL;
vector<int> rrh;

void init(){
  Lb = max(1, st - d + 1);
  Rb = min(n, st + d - 1);

  for(int i = Lb; i <= Rb; i++) rrh.push_back(a[i]);
  sort(rrh.begin(), rrh.end());
  rrh.erase(unique(rrh.begin(), rrh.end()), rrh.end());

  lim = rrh.size() - 1;
  for(int i = Lb; i <= Rb; i++) a[i] = lower_bound(rrh.begin(), rrh.end(), a[i]) - rrh.begin();
}

bool ok = false;

namespace IT{
  struct node{
    int cnt = 0;
    ll sum = 0LL;
  } st[N << 2];
  bool status[N];

  void upd(int pos, int x, int tl, int tr, int i){
    if(tl == tr){
      st[i].cnt += x;
      st[i].sum += x * rrh[tl];
      return;
    }
    int tm = tl + tr >> 1;
    if(pos <= tm) upd(pos, x, tl, tm, i<<1);
    else upd(pos, x, tm + 1, tr, i<<1|1);
    st[i].cnt = st[i<<1].cnt + st[i<<1|1].cnt;
    st[i].sum = st[i<<1].sum + st[i<<1|1].sum;
  }
  void update(int pos, int x){
    if(!status[pos]) upd(a[pos], x, 0, lim, 1);
    else upd(a[pos], -x, 0, lim, 1);
    status[pos] ^= 1;
  }
  ll get(int k, int tl, int tr, int i){
    if(tl == tr) return 1LL * rrh[tl] * min(k, st[i].cnt);
    int tm = tl + tr >> 1;

    if(st[i<<1|1].cnt >= k) return get(k, tm + 1, tr, i<<1|1);
    else return get(k - st[i<<1|1].cnt, tl, tm, i<<1) + st[i<<1|1].sum;
  }
  ll get_k(int k){ return get(k, 0, lim, 1); }
}

void solve(int l, int r, int optl, int optr){
  if(l > r) return;

//  cerr << l << " " << r << "\n";

  int mid = l + r >> 1;
  for(int i = mid; i <= r; i++) IT::update(i, 1);

  int opt = -1;
  ll cur = -1;

  for(int i = optl; i <= optr; i++){
    if(i > st) IT::update(i, 1);
    int tmp = min(2*i - st - mid, st + i - 2*mid); // mid st i

    ll val = IT::get_k(min(d - tmp, i - mid + 1));
    if(val > cur){
      cur = val;
      opt = i;
    }
  }
  res = max(res, cur);

  for(int i = max(st + 1, optl); i <= optr; i++) IT::update(i, 1);
  solve(l, mid - 1, optl, opt);


  for(int i = mid; i <= r; i++) IT::update(i, 1);
  for(int i = max(st + 1, optl); i < opt; i++) IT::update(i, 1);
  solve(mid + 1, r, opt, optr);

  for(int i = max(st + 1, optl); i < opt; i++) IT::update(i, 1);

  return;
}

ll findMaxAttraction(int _n, int _st, int _d, int _a[]){
  n = _n; st = _st + 1; d = _d;
  for(int i = 1; i <= n; i++) a[i] = _a[i - 1];

  init();
  solve(Lb, st, st, Rb);

  return res;
}

//#define zNatsumi
#ifdef zNatsumi

int32_t main(){
  cin.tie(0)->sync_with_stdio(0);
  #define task "test"
  if(fopen(task ".inp", "r")){
    freopen(task ".inp", "r", stdin);
    freopen(task ".out", "w", stdout);
  }
  int n, st, d, a[N];
  cin >> n >> st >> d;
  for(int i = 0; i < n; i++) cin >> a[i];
  cout << findMaxAttraction(n, st, d, a);

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