結果

問題 No.1332 Range Nearest Query
ユーザー lmorilmori
提出日時 2024-10-15 01:32:46
言語 C++23(gcc13)
(gcc 13.2.0 + boost 1.83.0)
結果
AC  
実行時間 531 ms / 2,500 ms
コード長 12,227 bytes
コンパイル時間 5,367 ms
コンパイル使用メモリ 301,212 KB
実行使用メモリ 37,504 KB
最終ジャッジ日時 2024-10-15 01:33:13
合計ジャッジ時間 24,391 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 3 ms
5,248 KB
testcase_03 AC 531 ms
33,280 KB
testcase_04 AC 428 ms
33,280 KB
testcase_05 AC 446 ms
33,152 KB
testcase_06 AC 298 ms
37,376 KB
testcase_07 AC 278 ms
37,504 KB
testcase_08 AC 223 ms
37,504 KB
testcase_09 AC 220 ms
37,376 KB
testcase_10 AC 255 ms
37,376 KB
testcase_11 AC 220 ms
37,376 KB
testcase_12 AC 219 ms
37,376 KB
testcase_13 AC 233 ms
37,504 KB
testcase_14 AC 222 ms
37,376 KB
testcase_15 AC 262 ms
37,504 KB
testcase_16 AC 443 ms
37,376 KB
testcase_17 AC 460 ms
37,504 KB
testcase_18 AC 479 ms
37,504 KB
testcase_19 AC 504 ms
37,504 KB
testcase_20 AC 474 ms
37,504 KB
testcase_21 AC 444 ms
37,376 KB
testcase_22 AC 479 ms
37,376 KB
testcase_23 AC 448 ms
37,504 KB
testcase_24 AC 470 ms
37,504 KB
testcase_25 AC 478 ms
37,376 KB
testcase_26 AC 199 ms
37,376 KB
testcase_27 AC 183 ms
37,376 KB
testcase_28 AC 30 ms
5,248 KB
testcase_29 AC 34 ms
5,248 KB
testcase_30 AC 37 ms
5,248 KB
testcase_31 AC 26 ms
5,248 KB
testcase_32 AC 38 ms
5,248 KB
testcase_33 AC 38 ms
5,248 KB
testcase_34 AC 31 ms
5,248 KB
testcase_35 AC 30 ms
5,248 KB
testcase_36 AC 31 ms
5,248 KB
testcase_37 AC 34 ms
5,248 KB
testcase_38 AC 278 ms
19,968 KB
testcase_39 AC 124 ms
5,248 KB
testcase_40 AC 523 ms
36,352 KB
testcase_41 AC 187 ms
8,832 KB
testcase_42 AC 278 ms
19,072 KB
testcase_43 AC 218 ms
12,800 KB
testcase_44 AC 391 ms
28,032 KB
testcase_45 AC 368 ms
25,216 KB
testcase_46 AC 255 ms
17,024 KB
testcase_47 AC 330 ms
22,656 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#pragma region Macros
#include <bits/stdc++.h>

using namespace std;
using lint = long long;
using ull = unsigned long long;
using ld = long double;
using int128 = __int128_t;
#define all(x) (x).begin(), (x).end()
#define EPS 1e-8
#define uniqv(v) v.erase(unique(all(v)), v.end())
#define OVERLOAD_REP(_1, _2, _3, name, ...) name
#define REP1(i, n) for (auto i = std::decay_t<decltype(n)>{}; (i) != (n); ++(i))
#define REP2(i, l, r) for (auto i = (l); (i) != (r); ++(i))
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
#define log(x) cout << x << endl
#define logfixed(x) cout << fixed << setprecision(10) << x << endl;
#define logy(bool)         \
  if (bool) {              \
    cout << "Yes" << endl; \
  } else {                 \
    cout << "No" << endl;  \
  }

ostream &operator<<(ostream &dest, __int128_t value) {
  ostream::sentry s(dest);
  if (s) {
    __uint128_t tmp = value < 0 ? -value : value;
    char buffer[128];
    char *d = end(buffer);
    do {
      --d;
      *d = "0123456789"[tmp % 10];
      tmp /= 10;
    } while (tmp != 0);
    if (value < 0) {
      --d;
      *d = '-';
    }
    int len = end(buffer) - d;
    if (dest.rdbuf()->sputn(d, len) != len) {
      dest.setstate(ios_base::badbit);
    }
  }
  return dest;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < (int)v.size(); i++) {
    os << v[i] << (i + 1 != (int)v.size() ? " " : "");
  }
  return os;
}

template <typename T>
ostream &operator<<(ostream &os, const set<T> &set_var) {
  for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
    os << *itr;
    ++itr;
    if (itr != set_var.end()) os << " ";
    itr--;
  }
  return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
  for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
    os << itr->first << " -> " << itr->second << "\n";
  }
  return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}

void out() { cout << '\n'; }
template <class T, class... Ts>
void out(const T &a, const Ts &...b) {
  cout << a;
  (cout << ... << (cout << ' ', b));
  cout << '\n';
}

template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (T &in : v) is >> in;
  return is;
}

inline void in(void) { return; }
template <typename First, typename... Rest>
void in(First &first, Rest &...rest) {
  cin >> first;
  in(rest...);
  return;
}

template <typename T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

vector<lint> dx8 = {1, 1, 0, -1, -1, -1, 0, 1};
vector<lint> dy8 = {0, 1, 1, 1, 0, -1, -1, -1};
vector<lint> dx4 = {1, 0, -1, 0};
vector<lint> dy4 = {0, 1, 0, -1};

#pragma endregion

template <class T>
class BitVector {
 private:
  unsigned n, cur, p;
  vector<unsigned> acc, bit;
  vector<T> srsum;

 public:
  BitVector() {
  }

  BitVector(vector<bool> &b) {
    cur = 0;
    n = b.size();
    acc.resize((n >> 5) + 2, 0);
    bit.resize((n >> 5) + 2, 0);
    srsum.resize(n + 1, 0);
    for (int i = 0; i < n; i++) {
      if (!(i & 31)) {
        cur++;
        acc[cur] = acc[cur - 1];
      }
      if (b[i]) {
        acc[cur] += int(b[i]);
        bit[cur - 1] |= (1U << (32 - (i & 31) - 1));
      }
    }
  }

  inline void srsum_set(const vector<T> &v) {
    for (int i = 0; i < n; i++) {
      srsum[i + 1] = srsum[i] + v[i];
    }
  }

  inline unsigned rank(unsigned k) {
    if (!(k & 31)) return acc[k >> 5];
    return acc[k >> 5] + __builtin_popcount(bit[k >> 5] >> (32 - (k & 31)));
  }

  inline T rank_srsum(unsigned k) {
    return srsum[k];
  }

  inline bool access(unsigned k) {
    return (rank(k + 1) - rank(k)) == 1;
  }
};

template <class T>
class WaveletMatrix {
 private:
  unsigned n;
  unsigned bitsize;
  vector<BitVector<T>> b;
  vector<unsigned> zero;
  vector<int> stInd;
  vector<unsigned> compressed;
  vector<T> cmp;
  vector<long long> sum;
  T MI, MA;

  // v[l,r) の中で値がk未満の総和を返す
  long long rank_sum(unsigned l, unsigned r, unsigned k) {
    long long less_sum = 0;
    for (unsigned i = 0; i < bitsize and l < r; i++) {
      const unsigned rank1_l = b[i].rank(l);
      const unsigned rank1_r = b[i].rank(r);
      const unsigned rank0_l = l - rank1_l;
      const unsigned rank0_r = r - rank1_r;
      if (k & (1U << (bitsize - i - 1))) {
        less_sum += b[i].rank_srsum(rank0_r) - b[i].rank_srsum(rank0_l);
        l = zero[i] + rank1_l;
        r = zero[i] + rank1_r;
      } else {
        l = rank0_l;
        r = rank0_r;
      }
    }
    return less_sum;
  }

  // v[l,r) の中で値がk未満の個数を返す
  unsigned rank_less(unsigned l, unsigned r, T k) {
    unsigned less = 0;
    for (unsigned i = 0; i < bitsize and l < r; i++) {
      const unsigned rank1_l = b[i].rank(l);
      const unsigned rank1_r = b[i].rank(r);
      const unsigned rank0_l = l - rank1_l;
      const unsigned rank0_r = r - rank1_r;
      if (k & (1U << (bitsize - i - 1))) {
        less += (rank0_r - rank0_l);
        l = zero[i] + rank1_l;
        r = zero[i] + rank1_r;
      } else {
        l = rank0_l;
        r = rank0_r;
      }
    }
    return less;
  }

  // v[l,r) の中で値がk未満の個数と総和を返す
  pair<long long, long long> rank_less_sum(unsigned l, unsigned r, T k) {
    long long less = 0;
    long long less_sum = 0;
    for (unsigned i = 0; i < bitsize and l < r; i++) {
      const unsigned rank1_l = b[i].rank(l);
      const unsigned rank1_r = b[i].rank(r);
      const unsigned rank0_l = l - rank1_l;
      const unsigned rank0_r = r - rank1_r;
      if (k & (1U << (bitsize - i - 1))) {
        less += (rank0_r - rank0_l);
        less_sum += b[i].rank_srsum(rank0_r) - b[i].rank_srsum(rank0_l);
        l = zero[i] + rank1_l;
        r = zero[i] + rank1_r;
      } else {
        l = rank0_l;
        r = rank0_r;
      }
    }
    return {less, less_sum};
  }

  inline unsigned compress(const T &x) {
    return lower_bound(cmp.begin(), cmp.end(), x) - begin(cmp);
  }

 public:
  // コンストラクタ
  WaveletMatrix() {}
  WaveletMatrix(vector<T> v) {
    MI = numeric_limits<T>::min();
    MA = numeric_limits<T>::max();
    n = v.size();
    cmp = v;
    sort(cmp.begin(), cmp.end());
    cmp.erase(unique(cmp.begin(), cmp.end()), cmp.end());
    compressed.resize(n);
    sum.resize(n + 1);
    vector<T> tmp(n);
    vector<unsigned> tmpc(n);
    unsigned size_mx = v.size();
    for (unsigned i = 0; i < n; i++) {
      compressed[i] = distance(cmp.begin(), lower_bound(cmp.begin(), cmp.end(), v[i]));
      sum[i + 1] = sum[i] + v[i];
    }
    stInd.resize(cmp.size() + 1, -1);
    bitsize = bit_width(size_mx);
    b.resize(bitsize);
    zero.resize(bitsize, 0);
    vector<bool> bit(n, 0);
    for (unsigned i = 0; i < bitsize; i++) {
      for (unsigned j = 0; j < n; j++) {
        bit[j] = compressed[j] & (1U << (bitsize - i - 1));
        zero[i] += unsigned(!bit[j]);
        tmp[j] = v[j];
        tmpc[j] = compressed[j];
      }
      b[i] = BitVector<T>(bit);
      int cur = 0;
      for (unsigned j = 0; j < n; j++) {
        if (!bit[j]) {
          v[cur] = tmp[j];
          compressed[cur] = tmpc[j];
          cur++;
        }
      }
      for (unsigned j = 0; j < n; j++) {
        if (bit[j]) {
          v[cur] = tmp[j];
          compressed[cur] = tmpc[j];
          cur++;
        }
      }
      b[i].srsum_set(v);
    }

    for (unsigned i = 0; i < n; i++) {
      if (stInd[compressed[i]] == -1) {
        stInd[compressed[i]] = i;
      }
    }
  }

  // get v[k]
  T access(unsigned k) {
    unsigned res = 0;
    unsigned cur = k;
    for (unsigned i = 0; i < bitsize; i++) {
      if (b[i].access(cur)) {
        res |= (1U << (bitsize - i - 1));
        cur = zero[i] + b[i].rank(cur);
      } else {
        cur -= b[i].rank(cur);
      }
    }
    return cmp[res];
  }

  // v[0,k) 中でのcの出現回数を返す
  unsigned rank(unsigned k, T c) {
    c = compress(c);
    unsigned cur = k;
    if (stInd[c] == -1) {
      return 0;
    }
    for (unsigned i = 0; i < bitsize; i++) {
      if (c & (1U << (bitsize - i - 1))) {
        cur = zero[i] + b[i].rank(cur);
      } else {
        cur -= b[i].rank(cur);
      }
    }
    return cur - stInd[c];
  }

  // v[l,r) の中でk番目(1-origin)に小さい値を返す
  T kth_smallest(unsigned l, unsigned r, unsigned k) {
    unsigned res = 0;
    for (unsigned i = 0; i < bitsize; i++) {
      unsigned num1 = b[i].rank(r) - b[i].rank(l);
      unsigned num0 = r - l - num1;
      if (num0 < k) {
        res |= (1ULL << (bitsize - i - 1));
        l = zero[i] + b[i].rank(l);
        r = zero[i] + b[i].rank(r);
        k -= num0;
      } else {
        l -= b[i].rank(l);
        r -= b[i].rank(r);
      }
    }
    return cmp[res];
  }

  // v[l,r) の中でk番目(1-origin)に大きい値を返す
  T kth_largest(unsigned l, unsigned r, unsigned k) {
    return kth_smallest(l, r, r - l - k + 1);
  }

  // v[l,r]を昇順ソートした時の先頭k個の総和を返す
  long long kth_ascending_sum(unsigned l, unsigned r, unsigned k) {
    long long res = 0;
    unsigned val = 0;
    for (unsigned i = 0; i < bitsize; i++) {
      const unsigned rank1_l = b[i].rank(l);
      const unsigned rank1_r = b[i].rank(r);
      const unsigned rank0_l = l - rank1_l;
      const unsigned rank0_r = r - rank1_r;
      const unsigned num1 = rank1_r - rank1_l;
      const unsigned num0 = rank0_r - rank0_l;
      if (num0 < k) {
        val |= (1ULL << (bitsize - i - 1));
        res += b[i].rank_srsum(rank0_r) - b[i].rank_srsum(rank0_l);
        l = zero[i] + rank1_l;
        r = zero[i] + rank1_r;
        k -= num0;
      } else {
        l = rank0_l;
        r = rank0_r;
      }
    }
    res += int64_t(cmp[val]) * (k);
    return res;
  }

  // v[l,r]を降順ソートした時の先頭k個の総和を返す
  long long kth_descending_sum(unsigned l, unsigned r, unsigned k) {
    return range_sum(l, r) - kth_ascending_sum(l, r, r - l - k);
  }

  // v[l,r) の中で[mink,maxk)に入る値の個数を返す
  unsigned range_freq(unsigned l, unsigned r, T mink, T maxk) {
    mink = compress(mink);
    maxk = compress(maxk);
    if (mink == 0) {
      return rank_less(l, r, maxk);
    }
    return rank_less(l, r, maxk) - rank_less(l, r, mink);
  }

  // v[l,r) の総和を返す
  long long range_sum(unsigned l, unsigned r) {
    return sum[r] - sum[l];
  }

  // v[l,r) の中で[mink,maxk)に入る値の総和を返す
  long long range_sum(unsigned l, unsigned r, T mink, T maxk) {
    mink = compress(mink);
    maxk = compress(maxk);
    return rank_sum(l, r, maxk) - rank_sum(l, r, mink);
  }

  // v[l,r) の中で ∑|v[i]-d| を計算して返す
  long long range_abs(unsigned l, unsigned r, T d) {
    T dnum = rank(r, d) - rank(l, d);
    T dsum = d * dnum;
    T asum = range_sum(l, r);
    auto p = rank_less_sum(l, r, compress(d));
    T less = p.first;
    T less_sum = p.second;
    T more = r - l - dnum - less;
    T more_sum = asum - dsum - less_sum;
    return d * less + more_sum - less_sum - (d * more);
  }

  // v[l,r)の中でvalを超えない最大の値を返す
  T prev_value(unsigned l, unsigned r, T val) {
    int num = range_freq(l, r, MI, val);
    if (num == 0) {
      return MA;
    } else {
      return kth_smallest(l, r, num);
    }
  }

  // v[l,r)の中でvalより大きい最小の値を返す
  T next_value(unsigned l, unsigned r, T val) {
    int num = range_freq(l, r, MI, val);
    if (num == r - l) {
      return MI;
    } else {
      return kth_smallest(l, r, num + 1);
    }
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n;
  in(n);
  vector<int> a(n);
  in(a);
  WaveletMatrix w(a);
  int q;
  in(q);
  rep(i, q) {
    int l, r, x;
    in(l, r, x);
    l--;
    int nex = w.next_value(l, r, x);
    int pre = w.prev_value(l, r, x);
    out(min(abs(x - nex), abs(pre - x)));
  }
}
0