結果
問題 |
No.878 Range High-Element Query
|
ユーザー |
![]() |
提出日時 | 2025-09-03 07:36:54 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 105 ms / 2,000 ms |
コード長 | 5,346 bytes |
コンパイル時間 | 3,670 ms |
コンパイル使用メモリ | 307,956 KB |
実行使用メモリ | 11,324 KB |
最終ジャッジ日時 | 2025-09-03 07:37:00 |
合計ジャッジ時間 | 6,487 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 18 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; bool chmin(auto &a, auto b) { return a > b ? a = b, true : false; } bool chmax(auto &a, auto b) { return a < b ? a = b, true : false; } #include <ranges> template<typename T, typename... Ts> vector<T> merge_and_unique(const vector<T> &a, const Ts &...z) { vector<T> res = a; (res.insert(res.end(), z.begin(), z.end()), ...); sort(res.begin(), res.end()); res.erase(unique(res.begin(), res.end()), res.end()); return res; } template<typename Abelian_Group> struct fenwick_tree { using M = Abelian_Group; using S = typename M::S; fenwick_tree() = default; fenwick_tree(int _n) : fenwick_tree(vector<S>(_n, M::e())) {} fenwick_tree(const vector<S> &_v) : n(_v.size()) { d = vector<S>(n, M::e()); v = vector<S>(n, M::e()); for (int i = 1; i <= n; i++) { v[i - 1] = _v[i - 1]; d[i - 1] += v[i - 1]; int j = i + (i & -i); if (j <= n) d[j - 1] += d[i - 1]; } } void add(int p, S x) { assert(0 <= p && p < n); v[p] = M::op(v[p], x); for (p++; p <= n; p += p & -p) { d[p - 1] = M::op(d[p - 1], x); } } void set(int p, S x) { assert(0 <= p && p < n); add(p, M::op(x, M::inv(v[p]))); } S prod(int l, int r) const { assert(0 <= l && l <= r && r <= n); return prod(r) - prod(l); } private: int n; vector<S> d, v; S prod(int p) const { S res = M::e(); for (; p > 0; p -= p & -p) { res = M::op(res, d[p - 1]); } return res; } }; template<typename Abelian_Group> struct range_add_fenwick_tree { using M = Abelian_Group; using S = typename M::S; range_add_fenwick_tree() = default; range_add_fenwick_tree(int n) : fw1(n + 1), fw2(n + 1) {} void add(int p, const S &x) { add(p, p + 1, x); } void add(int l, int r, const S &x) { fw1.add(l, M::inv(M::pow(x, l))); fw1.add(r, M::pow(x, r)); fw2.add(l, x); fw2.add(r, M::inv(x)); } S prod(int l, int r) const { return M::op(prod(r), M::inv(prod(l))); } private: fenwick_tree<Abelian_Group> fw1, fw2; S prod(int p) const { S res1 = fw1.prod(0, p); S res2 = fw2.prod(0, p); return M::op(res1, M::pow(res2, p)); } }; template<typename Abelian_Group, typename T = int> struct static_rectangle_add_point_get { using M = Abelian_Group; using S = typename M::S; static_rectangle_add_point_get() = default; static_rectangle_add_point_get(int n, int q) { xls.reserve(n); yls.reserve(n); xrs.reserve(n); yrs.reserve(n); ws.reserve(n); xs.reserve(q); ys.reserve(q); } void add_rectangle(T xl, T yl, T xr, T yr, const S &w) { xls.emplace_back(xl); yls.emplace_back(yl); xrs.emplace_back(xr); yrs.emplace_back(yr); ws.emplace_back(w); } void add_query(T x, T y) { xs.emplace_back(x); ys.emplace_back(y); } vector<S> solve() { int n = xls.size(), q = xs.size(); auto yb = merge_and_unique(ys); vector<tuple<int, int, T, S>> rs; rs.reserve(2 * n); for (int i = 0; i < n; i++) { int l = lower_bound(yb.begin(), yb.end(), yls[i]) - yb.begin(); int r = lower_bound(yb.begin(), yb.end(), yrs[i]) - yb.begin(); rs.emplace_back(l, r, xls[i], ws[i]); rs.emplace_back(l, r, xrs[i], M::inv(ws[i])); } sort(rs.begin(), rs.end(), [&] (auto a, auto b) { return get<2>(a) < get<2>(b); }); vector<int> ord(q); iota(ord.begin(), ord.end(), 0); sort(ord.begin(), ord.end(), [&] (int i, int j) { return xs[i] < xs[j]; }); range_add_fenwick_tree<Abelian_Group> fw(yb.size()); vector<S> res(q); int j = 0; for (int i : ord) { while (j < 2 * n && get<2>(rs[j]) <= xs[i]) { auto [l, r, _, w] = rs[j++]; fw.add(l, r, w); } int y = lower_bound(yb.begin(), yb.end(), ys[i]) - yb.begin(); res[i] = fw.prod(y, y + 1); } return res; } private: vector<T> xls, yls, xrs, yrs, xs, ys; vector<S> ws; }; template <typename T> struct add_monoid { using S = T; static S op(const S &a, const S &b) { return a + b; } static S e() { return 0; } static S inv(const S &x) { return -x; } static S pow(const S &x, long long k) { return x * k; } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N, Q; cin >> N >> Q; vector<int> A(N + 1); A[0] = 1 << 30; stack<int> st; st.push(0); static_rectangle_add_point_get<add_monoid<int>> RAPG(N, Q); for (int i = 1; i <= N; i++) { cin >> A[i]; while (A[st.top()] < A[i]) st.pop(); int j = st.top(); RAPG.add_rectangle(j + 1, i, i + 1, N + 1, 1); st.push(i); } while (Q--) { int t, l, r; cin >> t >> l >> r; RAPG.add_query(l, r); } for (auto a : RAPG.solve()) { cout << a << '\n'; } }