結果
問題 | No.1270 Range Arrange Query |
ユーザー | 👑 hos.lyric |
提出日時 | 2020-10-23 22:52:08 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,216 ms / 7,000 ms |
コード長 | 4,937 bytes |
コンパイル時間 | 1,346 ms |
コンパイル使用メモリ | 108,876 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-07-21 12:01:11 |
合計ジャッジ時間 | 7,755 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 2 ms
6,940 KB |
testcase_03 | AC | 2 ms
6,940 KB |
testcase_04 | AC | 2 ms
6,944 KB |
testcase_05 | AC | 2 ms
6,944 KB |
testcase_06 | AC | 76 ms
6,944 KB |
testcase_07 | AC | 700 ms
6,940 KB |
testcase_08 | AC | 112 ms
6,940 KB |
testcase_09 | AC | 464 ms
6,940 KB |
testcase_10 | AC | 471 ms
6,940 KB |
testcase_11 | AC | 1,216 ms
6,944 KB |
testcase_12 | AC | 1,208 ms
6,944 KB |
testcase_13 | AC | 1,210 ms
6,944 KB |
testcase_14 | AC | 14 ms
6,940 KB |
testcase_15 | AC | 52 ms
6,944 KB |
testcase_16 | AC | 46 ms
6,940 KB |
testcase_17 | AC | 45 ms
6,940 KB |
ソースコード
#include <cassert> #include <cmath> #include <cstdint> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <bitset> #include <complex> #include <deque> #include <functional> #include <iostream> #include <map> #include <numeric> #include <queue> #include <set> #include <sstream> #include <string> #include <unordered_map> #include <unordered_set> #include <utility> #include <vector> using namespace std; using Int = long long; template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; }; template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; } template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; } template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; } template <class T, class S, class OpTT, class OpST, class OpSS> struct SegmentTree { const OpTT opTT; const OpST opST; const OpSS opSS; const T idT; const S idS; int n; vector<T> ts; vector<S> ss; SegmentTree(int n_, const OpTT opTT, const OpST opST, const OpSS opSS, const T &idT, const S &idS) : opTT(opTT), opST(opST), opSS(opSS), idT(idT), idS(idS) { for (n = 1; n < n_; n <<= 1) {} ts.assign(n << 1, idT); ss.assign(n << 1, idS); } T &at(int a) { return ts[n + a]; } void build() { for (int a = n; --a; ) ts[a] = opTT(ts[a << 1], ts[a << 1 | 1]); } T query(int a, int b, const S &s) { return query(1, 0, n, a, b, s); } private: T query(int u, int l, int r, int a, int b, const S &s) { if (a < l) a = l; if (b > r) b = r; if (a >= b) return idT; if (a == l && b == r) { ts[u] = opST(s, ts[u], r - l); ss[u] = opSS(s, ss[u]); return ts[u]; } const int uL = u << 1, uR = u << 1 | 1; const int mid = (l + r) >> 1; // speed-up: if (ss[u] != idS) if (ss[u] != idS) { ts[uL] = opST(ss[u], ts[uL], mid - l); ts[uR] = opST(ss[u], ts[uR], r - mid); ss[uL] = opSS(ss[u], ss[uL]); ss[uR] = opSS(ss[u], ss[uR]); ss[u] = idS; } const T resL = query(uL, l, mid, a, b, s); const T resR = query(uR, mid, r, a, b, s); ts[u] = opTT(ts[uL], ts[uR]); return opTT(resL, resR); } }; constexpr int MAX_N = 20010; constexpr int MAX_Q = 20010; #ifdef LOCAL constexpr int B = 3; #else constexpr int B = 141; #endif int N, Q; int A[MAX_N]; struct Query { int l, r, id; }; Query P[MAX_Q]; int ans[MAX_Q]; int l, r; int bitL[MAX_N], bitR[MAX_N]; int now; void bitAdd(int *bit, int pos, int val) { for (int x = pos; x < N; x |= x + 1) bit[x] += val; } int bitSum(int *bit, int pos) { int ret = 0; for (int x = pos - 1; x >= 0; x = (x & (x + 1)) - 1) ret += bit[x]; return ret; } int opTT(int t0, int t1) { return min(t0, t1); } int opST(int s, int t, int sz) { return s + t; } int opSS(int s0, int s1) { return s0 + s1; } using Seg = SegmentTree<int, int, decltype(&opTT), decltype(&opST), decltype(&opSS)>; Seg *seg; void addL() { now += (l - bitSum(bitL, A[l] + 1)); now += bitSum(bitR, A[l]); bitAdd(bitL, A[l], +1); seg->query(0, A[l], +1); ++l; } void remL() { --l; bitAdd(bitL, A[l], -1); now -= (l - bitSum(bitL, A[l] + 1)); now -= bitSum(bitR, A[l]); seg->query(0, A[l], -1); } void addR() { --r; now += (l - bitSum(bitL, A[r] + 1)); now += bitSum(bitR, A[r]); bitAdd(bitR, A[r], +1); seg->query(A[r] + 1, N, +1); } void remR() { now -= (l - bitSum(bitL, A[r] + 1)); now -= bitSum(bitR, A[r]); bitAdd(bitR, A[r], -1); seg->query(A[r] + 1, N, -1); ++r; } int main() { for (; ~scanf("%d%d", &N, &Q); ) { for (int i = 0; i < N; ++i) { scanf("%d", &A[i]); --A[i]; } for (int q = 0; q < Q; ++q) { scanf("%d%d", &P[q].l, &P[q].r); --P[q].l; P[q].id = q; } sort(P, P + Q, [](const Query &a, const Query &b) { const int ax = a.l / B; const int bx = b.l / B; return ((ax != bx) ? (ax < bx) : (ax & 1) ? (a.r > b.r) : (a.r < b.r)); }); l = 0; r = N; fill(bitL, bitL + N, 0); fill(bitR, bitR + N, 0); now = 0; seg = new Seg(N, &opTT, &opST, &opSS, N + 1, 0); for (int j = 0; j < N; ++j) { seg->at(j) = 0; } seg->build(); for (int q = 0; q < Q; ++q) { // cerr<<"query "<<P[q].l<<" "<<P[q].r<<" "<<P[q].id<<endl; for (; l < P[q].l; addL()) {} for (; l > P[q].l; remL()) {} for (; r > P[q].r; addR()) {} for (; r < P[q].r; remR()) {} // cerr<<" now = "<<now<<endl; // cerr<<" seg:";for(int j=0;j<N;++j){cerr<<" "<<seg->query(j,j+1,0);}cerr<<endl; ans[P[q].id] = 0; ans[P[q].id] += now; ans[P[q].id] += (r - l) * seg->query(0, N, 0); } for (int q = 0; q < Q; ++q) { printf("%d\n", ans[q]); } } return 0; }