제출 #826731

#제출 시각아이디문제언어결과실행 시간메모리
826731Username4132Radio Towers (IOI22_towers)C++17
100 / 100
1076 ms65968 KiB
#include "towers.h"

#include<iostream>
#include <vector>
#include<algorithm>
using namespace std;
using pii = pair<int, int>;
#define forn(i, n) for(int i=0; i<(int)n; ++i)
#define dforn(i, n) for(int i=(int)n-1; i>=0; --i)
#define PB push_back
#define F first
#define S second
#define MP make_pair

const int MAXN = 100010, INF = 1000000010;

struct node{
  vector<pii> vec;
  vector<int> mn, mx;
  node(){};
  node(int value, int pos){
    vec.PB({value, pos});
    mn.PB(pos);
    mx.PB(pos);
  }
  node(node& a, node& b){
    vec.resize(a.vec.size() + b.vec.size());
    mn.resize(vec.size());
    mx.resize(vec.size());
    merge(a.vec.begin(), a.vec.end(), b.vec.begin(), b.vec.end(), vec.begin());
    int mi=MAXN, ma=-1;
    dforn(i, vec.size()){
      mi=min(mi, vec[i].S);
      ma=max(ma, vec[i].S);
      mn[i]=mi, mx[i]=ma;
    }
  }
};

int n, arr[MAXN], ml[MAXN], mr[MAXN], res[MAXN], sp[19][MAXN];
node tr[2*MAXN];

int spmin(int l, int r){
  if(r<=l) return INF;
  int sz = 8*sizeof(int) - __builtin_clz(r-l) - 1;
  return min(sp[sz][l], sp[sz][r-(1<<sz)]);
}

pair<int, pii> query(int l, int r, int x){
  int ret=0, mn=INF, mx=-1;
  for(l+=n, r+=n; l<r; l>>=1, r>>=1){
    if(l&1){
      auto itr = lower_bound(tr[l].vec.begin(), tr[l].vec.end(), MP(x, -1));
      int pos = (int)(itr - tr[l].vec.begin());
      ret += (int)(tr[l].vec.end() - itr);
      if(itr!=tr[l].vec.end()) mn=min(mn, tr[l].mn[pos]), mx=max(mx, tr[l].mx[pos]);
      ++l;
    }
    if(r&1){
      --r;
      auto itr = lower_bound(tr[r].vec.begin(), tr[r].vec.end(), MP(x, -1));
      int pos = (int)(itr - tr[r].vec.begin());
      ret += (int)(tr[r].vec.end() - itr);
      if(itr!=tr[r].vec.end()) mn=min(mn, tr[r].mn[pos]), mx=max(mx, tr[r].mx[pos]);
    }
  }
  return {ret, {mn, mx}};
}

void init(int N, vector<int> H) {
  n=N;
  forn(i, n) arr[i]=H[i];
  forn(i, n) sp[0][i]=H[i];
  forn(i, 18) forn(j, n-(1<<i)) sp[i+1][j]=min(sp[i][j], sp[i][j+(1<<i)]);

  forn(i, n){
    int x;
    for(x=i-1; x!=-1 && H[x]<H[i]; x=ml[x]);
    ml[i]=x;
  }

  dforn(i, n){
    int x;
    for(x=i+1; x!=n && H[x]<H[i]; x=mr[x]);
    mr[i]=x;
  }
  forn(i, n){
    int l = ml[i], r = mr[i];
    int a = H[i] - spmin(l+1, i);
    int b = H[i] - spmin(i+1, r);
    res[i] = min(a, b);
  }
  forn(i, n) tr[n+i]=node(res[i], i);
  dforn(i, n) tr[i]=node(tr[i<<1], tr[i<<1|1]);
}

int max_towers(int L, int R, int D) {
  pair<int, pii> ans = query(L, R+1, D);
  if(ans.F == 0) return 1;
  int sa = (spmin(L, ans.S.F) > arr[ans.S.F] - D);
  int sb = (spmin(ans.S.S+1, R+1) > arr[ans.S.S] - D);
  return max(0, ans.F - sa - sb) + 1;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...