제출 #1371043

#제출 시각아이디문제언어결과실행 시간메모리
1371043eradaxExponents (BOI25_exp)C++20
37 / 100
1100 ms123684 KiB
#pragma GCC optimize("O3")
#include <bits/allocator.h>
#pragma GCC target("avx2")
#include <bits/stdc++.h>
using namespace std;

// #define dbg(expr)                                                          \
  //   cerr << "[" << __FUNCTION__ << ", " << __LINE__ << "] " << #expr << ": " \
  //        << expr << endl;
#ifdef DBG
  #include "../../../../dbg.h"
#else
  #define dbg(...)
#endif

ostream& operator<<(ostream& o, vector<int> v) {
  o << "{";
  for (auto i : v)
    o << i << ", ";
  o << "}";
  return o;
}

#define sz(c) ((int)c.size())

const int INF = 1e9;

const int MX = 1e6 + 1;
const int NL = __bit_width((unsigned)MX) * 2;

using vi = vector<int>;
using vvi = vector<vi>;

struct RMQ {
  int n;
  vi t;

  RMQ(int n) : n(n), t(2 * n) {}
  void set(int i, int v) {
    for (t[i += n] = v; i > 1; i /= 2)
      t[i / 2] = max(t[i], t[i ^ 1]);
  }

  int query(int l, int r) {
    int ans = 0;

    for (l += n, r += n; l < r; l /= 2, r /= 2) {
      if (l & 1)
        ans = max(ans, t[l++]);
      if (r & 1)
        ans = max(ans, t[--r]);
    }

    return ans;
  }
};

int main() {
  cin.tie(0)->sync_with_stdio(0);

  int n, q;
  cin >> n >> q;

  RMQ rmq(n);
  vvi groups(MX);

  for (int i = 0; i < n; i++) {
    int v;
    cin >> v;

    rmq.set(i, v);
    groups[v].push_back(i);
  }

  auto calc_dp = [](vvi& dp, vi a) {
    int n = sz(a);
    dp.assign(n, vi(NL, -1));

    for (int i = 0; i < n; i++)
      for (int j = a[i]; j < NL; j++)
        dp[i][j] = i;

    for (int i = n - 1; i >= 0; i--) {
      for (int j = 1; j < NL; j++) {
        int nod = dp[i][j - 1];
        if (nod == -1)
          continue;

        dp[i][j] = nod;

        if (nod == n - 1)
          continue;

        int nxt_nod = dp[nod + 1][j - 1];

        if (nxt_nod == -1)
          continue;

        dp[i][j] = nxt_nod;
      }
    }
  };

  vector<vector<array<int, 3>>> queries(MX);
  vi res(q);

  for (int i = 0; i < q; i++) {
    int l, r;
    cin >> l >> r;
    l--, r--;

    int mx = rmq.query(l, r + 1);

    queries[mx].push_back({l, r, i});
  }

  for (int i = 0; i < MX; i++) {
    if (!sz(queries[i]))
      continue;

    int mn = max(i - NL / 2, 0);
    dbg(mn);
    vector<pair<int, int>> b;
    for (int j = mn; j <= i; j++)
      for (auto k : groups[j])
        b.emplace_back(k, j - mn);

    sort(b.begin(), b.end());

    dbg(b);

    vi bcomp;
    vi pos, p2p;
    if (b[0].first != 0) {
      bcomp.push_back(0);
    }
    pos.push_back(b[0].first);
    p2p.push_back(sz(bcomp));
    bcomp.push_back(b[0].second);

    for (int j = 1; j < sz(b); j++) {
      if (b[j-1].first + 1 != b[j].first) {
        bcomp.push_back(0);
      }

      pos.push_back(b[j].first);
      p2p.push_back(sz(bcomp));
      bcomp.push_back(b[j].second);
    }

    if (b.back().first != n-1) {
      bcomp.push_back(0);
    }

    vvi dp;
    calc_dp(dp, bcomp);

    dbg(pos, p2p);
    dbg(bcomp);
    dbg(queries);

    for (auto [l, r, k] : queries[i]) {
      int ll = lower_bound(pos.begin(), pos.end(), l) - pos.begin();
      int rr = upper_bound(pos.begin(), pos.end(), r) - pos.begin() - 1;

      // dbg(ll, rr);


      int lll = p2p[ll];
      lll -= pos[ll] > l;

      int rrr = p2p[rr];
      rrr += pos[rr] < r;

      dbg(l, r);
      dbg(ll, rr);
      dbg(lll, rrr);

      int ans = -1;
      for (int j = 0; j < NL; j++) {
        if (dp[lll][j] >= rrr) {
          ans = j;
          break;
        }
      }

      res[k] = ans + mn;
    }
  }


  for (auto i : res)
    cout << i << '\n';
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…