Submission #338473

#TimeUsernameProblemLanguageResultExecution timeMemory
338473KoDBubble Sort 2 (JOI18_bubblesort2)C++17
38 / 100
9080 ms55276 KiB
#include <bits/stdc++.h> template <class T> using Vec = std::vector<T>; struct Fenwick { Vec<int> data; Fenwick(int n): data(n + 1) { } void add(int i, int x) { i += 1; while (i < (int) data.size()) { data[i] += x; i += (i & -i); } } int get(int i) { int ret = 0; while (i > 0) { ret += data[i]; i -= (i & -i); } return ret; } }; struct Mn { int value; static Mn id() { return Mn { -1000000000 }; } Mn operator + (const Mn other) const { return Mn { std::max(value, other.value) }; } }; struct Ef { int add; static Ef id() { return Ef { 0 }; } Ef operator + (const Ef other) const { return Ef { add + other.add }; } }; Mn operator + (const Mn mn, const Ef ef) { return Mn { mn.value + ef.add }; } struct Segtree { struct Node { Mn mn; Ef ef; }; void fetch(const int i) { data[i].mn = data[i * 2 + 0].mn + data[i * 2 + 1].mn; } void apply(const int i, const Ef ef) { data[i].mn = data[i].mn + ef; data[i].ef = data[i].ef + ef; } void flush(const int i) { apply(i * 2 + 0, data[i].ef); apply(i * 2 + 1, data[i].ef); } static int ctzr(const int i) { return __builtin_ctzll(i); } static int height(const int i) { return 64 - __builtin_clzll(i); } void pushdown(const int i) { const auto lsb = ctzr(i); for (int d = height(i); --d > lsb;) { flush(i >> d); } } void pullup(int i) { i >>= ctzr(i); while (i != 1) { i >>= 1; fetch(i); } } Vec<Node> data; Segtree(const Vec<int> &vec) { const auto size = vec.size(); data.resize(size * 2, Node { Mn::id(), Ef::id() }); for (int i = 0; i < size; ++i) { data[size + i].mn.value = vec[i]; } for (int i = size - 1; i > 0; --i) { fetch(i); } } void operate(int l, int r, const int x) { l += size(); r += size(); pushdown(l); pushdown(r); const auto cl = l; const auto cr = r; const auto ef = Ef { x }; while (l < r) { if (l & 1) { apply(l, ef); l += 1; } if (r & 1) { r -= 1; apply(r, ef); } l >>= 1; r >>= 1; } pullup(cl); pullup(cr); } int fold(int l, int r) { l += size(); r += size(); pushdown(l); pushdown(r); Mn mn = Mn::id(); while (l < r) { if (l & 1) { mn = mn + data[l].mn; l += 1; } if (r & 1) { r -= 1; mn = mn + data[r].mn; } l >>= 1; r >>= 1; } return mn.value; } int assign(int i, int x) { i += size(); pushdown(i); pushdown(i + 1); data[i].mn = Mn { x }; data[i].ef = Ef::id(); while (i > 1) { i >>= 1; fetch(i); } } int size() const { return data.size() / 2; } }; Vec<int> countScans(Vec<int> A, Vec<int> X, Vec<int> V) { const int N = A.size(); const int Q = X.size(); if (N <= 8000 && Q <= 8000) { Vec<int> big(N); for (int i = 0; i < N; ++i) { for (int j = 0; j < i; ++j) { if (A[j] > A[i]) { big[i] += 1; } } } Vec<int> ret(Q); for (int i = 0; i < Q; ++i) { for (int j = X[i] + 1; j < N; ++j) { if (A[X[i]] <= A[j] && V[i] > A[j]) { big[j] += 1; } if (A[X[i]] > A[j] && V[i] <= A[j]) { big[j] -= 1; } } A[X[i]] = V[i]; big[X[i]] = 0; for (int j = 0; j < X[i]; ++j) { if (A[j] > A[X[i]]) { big[X[i]] += 1; } } ret[i] = *std::max_element(big.begin(), big.end()); } return ret; } else { for (auto &x: A) { x -= 1; if (x >= 100) { return { }; } } for (auto &x: V) { x -= 1; if (x >= 100) { return { }; } } Vec<Fenwick> fen(100, Fenwick(N)); Vec<Segtree> seg(100, Segtree(Vec<int>(N, -1000000000))); for (int i = 0; i < N; ++i) { fen[A[i]].add(i, 1); int sum = 0; for (int j = V[i] + 1; j < 100; ++j) { sum += fen[j].get(i); } seg[A[i]].assign(i, sum); } Vec<int> ret(Q); for (int i = 0; i < Q; ++i) { int sum = 0; for (int j = V[i] + 1; j < 100; ++j) { sum += fen[j].get(X[i]); } fen[A[X[i]]].add(X[i], -1); seg[A[X[i]]].assign(X[i], -1000000000); fen[V[i]].add(X[i], 1); seg[V[i]].assign(X[i], sum); if (A[X[i]] < X[i]) { for (int j = A[X[i]]; j < V[j]; ++j) { seg[j].operate(X[i] + 1, N, 1); } } else { for (int j = V[i]; j < A[X[i]]; ++j) { seg[j].operate(X[i] + 1, N, -1); } } A[X[i]] = V[i]; for (int j = 0; j < 100; ++j) { ret[i] = std::max(ret[i], seg[j].fold(0, N)); } } return ret; } } #ifdef __APPLE__ int main() { int N, Q; std::cin >> N >> Q; Vec<int> A(N); Vec<int> X(Q), V(Q); for (auto &x: A) { std::cin >> x; } for (int i = 0; i < Q; ++i) { std::cin >> X[i] >> V[i]; } for (auto x: countScans(A, X, V)) { std::cout << x << '\n'; } return 0; } #endif

Compilation message (stderr)

bubblesort2.cpp: In constructor 'Segtree::Segtree(Vec<int>&)':
bubblesort2.cpp:96:27: warning: comparison of integer expressions of different signedness: 'int' and 'const long unsigned int' [-Wsign-compare]
   96 |         for (int i = 0; i < size; ++i) {
      |                         ~~^~~~~~
bubblesort2.cpp: In member function 'int Segtree::assign(int, int)':
bubblesort2.cpp:159:5: warning: no return statement in function returning non-void [-Wreturn-type]
  159 |     }
      |     ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...