結果
問題 | No.1270 Range Arrange Query |
ユーザー |
![]() |
提出日時 | 2020-10-22 13:58:21 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 3,286 ms / 7,000 ms |
コード長 | 5,266 bytes |
コンパイル時間 | 2,455 ms |
コンパイル使用メモリ | 219,496 KB |
最終ジャッジ日時 | 2025-01-15 12:26:44 |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 15 |
ソースコード
#include <bits/stdc++.h>using namespace std;using ll = long long int;#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)#define rep(i, n) REP(i, 0, n)template <typename T>struct BIT{int n;vector<T> dat;BIT() {}BIT(int n_) : n(n_), dat(n_, 0) {}// 0-indexedvoid add(int i, T x){i++;while (i <= n){dat[i - 1] += x;i += i & -i;}}// [0, i)T sum(int i){T res = 0;while (i > 0){res += dat[i - 1];i -= i & -i;}return res;}// 0-indexedT get(int i) { return sum(i + 1) - sum(i); }// [l, r)T sum(int l, int r) { return sum(r) - sum(l); }};template <typename T, typename E>struct SegmentTree{using F = function<T(T, T)>;using G = function<T(T, E)>;using H = function<E(E, E)>;using P = function<E(E, int)>;int n;F f;G g;H h;P p;T ti;E ei;vector<T> dat;vector<E> laz;SegmentTree() {}SegmentTree(int n_, F f, G g, H h, T ti, E ei, P p = [](E a, int b) { return a; }): f(f), g(g), h(h), ti(ti), ei(ei), p(p){init(n_);}SegmentTree(vector<T> &v, F f, G g, H h, T ti, E ei, P p = [](E a, int b) { return a; }): f(f), g(g), h(h), ti(ti), ei(ei), p(p){init(v.size());build(v);}void init(int n_){n = 1;while (n < n_)n *= 2;dat.clear();dat.resize(2 * n - 1, ti);laz.clear();laz.resize(2 * n - 1, ei);}void build(const vector<T> v){for (int i = 0; i < v.size(); i++)dat[i + n - 1] = v[i];for (int i = n - 2; i >= 0; i--)dat[i] = f(dat[i * 2 + 1], dat[i * 2 + 2]);}void eval(int len, int k){if (laz[k] == ei)return;if (k * 2 + 1 < n * 2 - 1){laz[k * 2 + 1] = h(laz[k * 2 + 1], laz[k]);laz[k * 2 + 2] = h(laz[k * 2 + 2], laz[k]);}dat[k] = g(dat[k], p(laz[k], len));laz[k] = ei;}T update(int a, int b, E x, int k, int l, int r){eval(r - l, k);if (r <= a || b <= l)return dat[k];if (a <= l && r <= b){laz[k] = h(laz[k], x);return g(dat[k], p(laz[k], r - l));}return dat[k] = f(update(a, b, x, k * 2 + 1, l, (l + r) / 2),update(a, b, x, k * 2 + 2, (l + r) / 2, r));}T update(int a, int b, E x) { return update(a, b, x, 0, 0, n); }T query(int a, int b, int k, int l, int r){eval(r - l, k);if (r <= a || b <= l)return ti;if (a <= l && r <= b)return dat[k];T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);return f(vl, vr);}T query(int a, int b) { return query(a, b, 0, 0, n); }};auto my_min = [](ll a, ll b) { return min(a, b); };int n;vector<int> a;BIT<ll> bit_l, bit_r;SegmentTree<ll, ll> sg;ll inv = 0;struct Mo{vector<int> left, right, order;vector<vector<bool>> v;int width;int nl, nr, ptr;Mo(int n) : width((int)sqrt(n)), nl(0), nr(0), ptr(0), v(vector<vector<bool>>(n, vector<bool>(2, 0))) {}void insert(int l, int r) /* [l, r) */{left.push_back(l);right.push_back(r);}/* ソート */void build(){order.resize(left.size());iota(begin(order), end(order), 0);sort(begin(order), end(order), [&](int a, int b) {if (left[a] / width != left[b] / width)return left[a] < left[b];return right[a] < right[b];});}/* クエリを 1 つぶんすすめて, クエリのidを返す */int process(){if (ptr == order.size())return -1;const auto id = order[ptr];while (nl > left[id])distribute(--nl, 0);while (nr < right[id])distribute(nr++, 1);while (nl < left[id])distribute(nl++, 0);while (nr > right[id])distribute(--nr, 1);return order[ptr++];}inline void distribute(int idx, bool R){v[idx][R].flip();if (v[idx][R] ^ !R)add(idx, R);elsedel(idx, R);}void add(int idx, bool R){if (!R) // left{sg.update(0, a[idx], -1);bit_l.add(a[idx], -1);}else // right{sg.update(a[idx] + 1, n, -1);bit_r.add(a[idx], -1);}inv -= bit_l.sum(a[idx] + 1, n) + bit_r.sum(0, a[idx]);}void del(int idx, bool R){if (!R) // left{sg.update(0, a[idx], 1);bit_l.add(a[idx], 1);}else // right{sg.update(a[idx] + 1, n, 1);bit_r.add(a[idx], 1);}inv += bit_l.sum(a[idx] + 1, n) + bit_r.sum(0, a[idx]);}};int main(){int q;cin >> n >> q;bit_l = BIT<ll>(n), bit_r = BIT<ll>(n);vector<ll> sg_init(n, 0);sg = SegmentTree<ll, ll>(sg_init, my_min, plus<ll>(), plus<ll>(), (ll)1e18, 0LL);a.resize(n);rep(i, n){cin >> a[i];a[i]--;}for (int i = n - 1; i >= 0; i--){inv += bit_r.sum(0, a[i]);bit_r.add(a[i], 1);}Mo mo(n);vector<ll> l(q), r(q);rep(i, q){cin >> l[i] >> r[i];l[i]--;mo.insert(l[i], r[i]);}mo.build();rep(i, n) sg.update(a[i] + 1, n, 1);vector<int> ans(q);rep(qi, q){int i = mo.process();ans[i] = inv + sg.query(0, n) * (r[i] - l[i]);}rep(i, q) cout << ans[i] << "\n";}