Submission #484808

# Submission time Handle Problem Language Result Execution time Memory
484808 2021-11-05T14:28:54 Z Felerius Deda (COCI17_deda) C++17
140 / 140
43 ms 6632 KB
#pragma GCC optimize("fast-math")
// begin "cp-lib/prelude.hpp"
#include <bits/stdc++.h>
#ifdef LOCAL
#  include <dbg.h>
#else
#  define dbg(...) do {} while (0)
#endif

#define cp_lib_4th(_1, _2, _3, x, ...)  x
#define cp_lib_rep(i, l, r)             for (int i = (l); (i) < (r); ++(i))
#define cp_lib_rep0(i, r)               cp_lib_rep(i, 0, r)
#define rep(...)                        cp_lib_4th(__VA_ARGS__, cp_lib_rep, cp_lib_rep0, _)(__VA_ARGS__)
#define cp_lib_repr(i, r, l, ...)       for (int i = (r); (i) >= (l); --(i))
#define repr(...)                       cp_lib_repr(__VA_ARGS__, 0)
#define all(a)                          ::begin(a),::end(a)
#define trav(a, b)                      for (auto&& a : (b))

using namespace std;
using ll = long long;
using ld = long double;
[[maybe_unused]] static constexpr int INF = int(1e9 + 5);
[[maybe_unused]] static constexpr ll INFL = ll(INF) * INF;
template <class C> int sz(const C& c) { return int(::size(c)); }
// end "cp-lib/prelude.hpp"
// begin "cp-lib/io.hpp"
// begin "_assert.hpp"
#ifdef CP_LIB_DEBUG
#define cp_lib_assert(expr) \
    do { if (!(expr)) { \
        ::cerr << "assertion failed: " << #expr << " (" << __FILE__ << ':' << __LINE__ << ")\n"; \
        ::abort(); \
    } } while (0)
#else
#define cp_lib_assert(expr)
#endif
// end "_assert.hpp"
// begin "_type-meta.hpp"
#if __cplusplus < 202002L
struct identity { template <class T> constexpr T&& operator()(T&& t) const noexcept { return forward<T>(t); }; };
template <class T> using remove_cvref_t = remove_cv_t<remove_reference_t<T>>;
#endif

namespace cp_lib_type_meta {
    struct NoOp { template <class... Args> void operator()(Args&&...) const noexcept {} };
    template <class T, class = void> constexpr bool is_tuple_like = false;
    template <class T> constexpr bool is_tuple_like<T, void_t<tuple_element_t<0, T>>> = true;
}
// end "_type-meta.hpp"
// begin "modint/_detect.hpp"
namespace cp_lib_modint { struct ModIntTag {}; }
// end "modint/_detect.hpp"
#include <unistd.h>

namespace cp_lib_io {
    constexpr int BUF_SIZE = 1 << 20;
    array<char, BUF_SIZE> ibuf, obuf;
    char *iptr = data(ibuf), *iend = iptr, *optr = data(obuf);

    template <class T> constexpr bool is_std_array = false;
    template <class T, size_t I> constexpr bool is_std_array<array<T, I>> = true;

    void flush() {
        auto* p = begin(obuf);
        while (p != optr)
            p += write(STDOUT_FILENO, p, optr - p);
        optr = begin(obuf);
    }
    void ensure_write(int l) { if (end(obuf) - optr < l) flush(); }
    int _flush_atexit = []{ atexit(flush); return 0; }();
    void refill() {
        memmove(begin(ibuf), iptr, iend - iptr);
        iend -= iptr - begin(ibuf);
        iptr = begin(ibuf);
        iend += read(STDIN_FILENO, iend, end(ibuf) - iend);
    }
    void skip_ensure_read(int l) {
        do {
            while (iptr != iend && *iptr <= ' ') ++iptr;
            if (iend - iptr < l) refill();
        } while (*iptr <= ' ');
    }

    template <class T, class T2 = remove_reference_t<remove_cv_t<T>>>
    void print(T&& val) {
        if constexpr (is_same_v<T2, char>)
            ensure_write(2), *optr++ = val;
        else if constexpr (is_integral_v<T2> && !is_same_v<T2, bool>) {
            ensure_write(numeric_limits<T>::digits10 + 1 + is_signed_v<T2>);
            if (val < 0) { *optr++ = '-'; print(make_unsigned_t<T2>(-make_unsigned_t<T2>(val))); return; }
            array<char, 128> tmp;
            char* tptr = end(tmp);
            remove_const_t<T2> val_copy = val;
            do { *--tptr = char('0' + val_copy % 10), val_copy /= 10; } while (val_copy);
            memcpy(optr, tptr, end(tmp) - tptr);
            optr += end(tmp) - tptr;
#if __cpp_lib_to_chars >= 201611
        } else if constexpr (is_floating_point_v<T2>) {
            ensure_write(64);
            auto res = to_chars(optr, end(obuf), val, chars_format::fixed, 30);
            cp_lib_assert(res.ec == errc());
            optr = res.ptr;
#endif
        } else if constexpr (is_convertible_v<T, string_view>) {
            string_view sv(val);
            if (sz(sv) + 1 <= end(obuf) - optr)
                memcpy(optr, data(sv), sz(sv)), optr += sz(sv);
            else {
                flush();
                for (auto *p = data(sv), *pe = p + sz(sv); p != end(sv); )
                    p += write(STDOUT_FILENO, p, pe - p);
            }
        } else {
            if constexpr (is_same_v<T2, bool> || is_same_v<T2, vector<bool>::reference>)
                print(int(val));
            else if constexpr (is_base_of_v<cp_lib_modint::ModIntTag, T2>)
                print(decltype(T2::mod())(val));
            else if constexpr (cp_lib_type_meta::is_tuple_like<T2> && !is_std_array<T2>)
                apply([](auto&&... items) { (print(items), ...); }, forward<T>(val));
            else
                trav(item, val) print(item);
            return;
        }
        *optr++ = ' ';
    }

    template <class T>
    void read(T& val) {
        if constexpr (is_same_v<T, char>)
            skip_ensure_read(1), val = *iptr++;
        else if constexpr (is_same_v<T, bool> || is_same_v<T, vector<bool>::reference>) {
            uint8_t ival; read(ival), val = bool(ival);
        } else if constexpr (is_base_of_v<cp_lib_modint::ModIntTag, T>) {
            ll ival; read(ival); val = T(ival);
        } else if constexpr (is_integral_v<T>) {
            skip_ensure_read(numeric_limits<T>::digits10 + 1 + is_signed_v<T>);
            if (is_signed_v<T> && *iptr == '-') {
                ++iptr;
                make_unsigned_t<T> uval;
                read(uval);
                val = T(-uval);
            } else {
                val = 0;
                while (iptr != iend && *iptr > ' ') val = T(10 * val + (*iptr++ - '0'));
            }
#if __cpp_lib_to_chars >= 201611
        } else if constexpr (is_floating_point_v<T>) {
            skip_ensure_read(128);
            auto res = from_chars(iptr, iend, val);
            assert(res.ec == errc());
            iptr = const_cast<char*>(res.ptr);
#endif
        } else if constexpr (is_same_v<T, string>) {
            val = string();
            skip_ensure_read(1);
            do {
                auto* after = iptr;
                while (after != iend && *after > ' ') ++after;
                copy(iptr, after, back_inserter(val));
                if ((iptr = after) == iend)
                    refill();
                else
                    break;
            } while (iptr != iend);
        } else if constexpr (cp_lib_type_meta::is_tuple_like<T> && !is_std_array<T>)
            apply([](auto&... items) { (read(items), ...); }, val);
        else
            trav(item, val) read(item);
    }
}

using cp_lib_io::flush;

template <class... Args>
void print(Args&&... args) { (cp_lib_io::print(forward<Args>(args)), ...); }

template <class... Args>
void println(Args&&... args) {
    if (sizeof...(Args) > 0)
        (cp_lib_io::print(forward<Args>(args)), ...), *(cp_lib_io::optr - 1) = '\n';
    else
        cp_lib_io::ensure_write(1), *cp_lib_io::optr++ = '\n';
}

template <class... Args>
void printlns(Args&&... args) {
    ((cp_lib_io::print(forward<Args>(args)), *(cp_lib_io::optr - 1) = '\n'), ...);
}

template <class... Args>
void read(Args&... args) { (cp_lib_io::read(args), ...); }
// end "cp-lib/io.hpp"

template <class Data, class Combine>
class SegmentTree {
    int n;
    const Data identity;
    Combine combine;
    vector<Data> tree;

    void recalc(int i) { tree[i] = combine(tree[i << 1], tree[(i << 1) | 1]); }
    void rebuild(int i) { for (i >>= 1; i; i >>= 1) recalc(i); }

    template <class Pred>
    int lower_bound_full(int v, Data prefix, Pred&& pred) {
        while (v < n)
            if (auto prefix2 = identity; !pred(prefix2 = combine(prefix, tree[v <<= 1])))
                ++v, prefix = prefix2;
        return v - n;
    }

 public:
    SegmentTree(int n_, Data identity_, Combine combine_)
        : n(n_), identity(identity_), combine(move(combine_)), tree(2 * n, identity) {}

    template <class It, class ItEnd>
    SegmentTree(It it, It it_end, Data identity_, Combine combine_)
        : SegmentTree(int(it_end - it), identity_, move(combine_)) {
        copy(it, it_end, begin(tree) + n);
        build();
    }

    Data& root() { return tree[1]; }
    Data& leaf(int i) { return tree[i + n]; }

    void build() { repr(i, n - 1, 1) recalc(i); }

    Data query(int l, int r) {
        auto left = identity, right = identity;
        for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
            if (l & 1) left = combine(left, tree[l++]);
            if (r & 1) right = combine(right, tree[--r]);
        }
        return combine(left, right);
    }

    template <class Update>
    void point_update(int i, Update&& update) {
        update(tree[i + n]);
        rebuild(i + n);
    }

    template <class Pred>
    int lower_bound(int l, int r, Pred&& pred) {
        auto prefix = identity;
        array<int, 32> nodes;
        int cnt = 0;
        for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
            if (auto old_prefix = prefix; l & 1 && pred(prefix = combine(prefix, tree[l++])))
                return lower_bound_full(l - 1, old_prefix, forward<Pred>(pred));
            if (r & 1)
                nodes[cnt++] = --r;
        }
        repr(i, cnt - 1)
            if (auto old_prefix = prefix; pred(prefix = combine(prefix, tree[nodes[i]])))
                return lower_bound_full(nodes[i], old_prefix, forward<Pred>(pred));
        return n;
    }
};

int main() {
    int n, q; read(n, q);
    SegmentTree seg(n, INF, [](int a, int b) { return min(a, b); });
    vector vals(n, INF);
    while (q--) {
        char ty; int a, i; read(ty, a, i); --i;
        if (ty == 'M')
            seg.point_update(i, [&](int& val) { val = a; });
        else {
            int ans = seg.lower_bound(i, n, [&](int mn) { return mn <= a; });
            println(ans == n ? -1 : ans + 1);
        }
    }
}
# Verdict Execution time Memory Grader output
1 Correct 0 ms 296 KB Output is correct
2 Correct 1 ms 292 KB Output is correct
3 Correct 1 ms 332 KB Output is correct
4 Correct 43 ms 6632 KB Output is correct
5 Correct 29 ms 4040 KB Output is correct
6 Correct 33 ms 4820 KB Output is correct
7 Correct 43 ms 5444 KB Output is correct