제출 #1299095

#제출 시각아이디문제언어결과실행 시간메모리
1299095goppamachGrowing Trees (BOI11_grow)C++20
100 / 100
483 ms7840 KiB
// #pragma GCC optimize("Ofast")

#include <bits/stdc++.h>

using namespace std;

#define el "\n"
#define pii pair<int, int>
#define pll pair<ll, ll>
#define fi first
#define se second
#define mp make_pair
#define sqr(x) ((x) * (x))
#define FOR(i, l, r) for (int i = l; i <= (r); i++)
#define FOD(i, l, r) for (int i = l; i >= (r); i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define sz(x) ((int)(x).size())
#define fast_io ios_base::sync_with_stdio(false); cin.tie(nullptr);

using db = long double;
using ll = long long;
using ull = unsigned long long;
using vi = vector<int>;
using vll = vector<ll>;
using vpii = vector<pii>;
using vpll = vector<pll>;
using vvi = vector<vi>;
using vvll = vector<vll>;
using vbool = vector<bool>;
using vvbool = vector<vbool>;

template<class T> inline bool chmax(T &a, T const &b) { return (a < b ? (a = b, true) : false); }
template<class T> inline bool chmin(T &a, T const &b) { return (a > b ? (a = b, true) : false); }

// #define DEBUG
#ifdef DEBUG
#include "D:\cpp\debug.h"
#else
#define debug(...)
#define debug_arr(...)
#endif

mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

constexpr int N = 1E5 + 5;
constexpr int INF = 1E9 + 7;
constexpr ll INFLL = 4E18;
constexpr int MOD = 1E9 + 7; // 998244353
constexpr double EPS = 1E-10;

template<typename T> int first_true(int l, int r, T f) {
    ++r;
    while (l < r) {
        int m = (l + r) / 2;
        if (f(m)) r = m;
        else l = m + 1;
    }
    return l;
}

struct SegmentTree {
private:
    int n;
    vll tree, lazy;

    void build(vll const &a, int i, int l, int r) {
        if (l == r) {
            tree[i] = a[l];
            return;
        }
        int m = (l + r) / 2;
        build(a, i * 2, l, m);
        build(a, i * 2 + 1, m + 1, r);
        tree[i] = tree[i * 2] + tree[i * 2 + 1];
    }

    void apply(int i, int len, int val) {
        tree[i] += 1LL * val * len;
        lazy[i] += val;
    }

    void push(int i, int l, int r) {
        int m = (l + r) / 2;
        apply(i * 2, m - l + 1, lazy[i]);
        apply(i * 2 + 1, r - m, lazy[i]);
        lazy[i] = 0;
    }
public:
    SegmentTree(int n): n(n), tree(4 * n + 5), lazy(4 * n + 5) {}
    SegmentTree(vll const &a, int n): n(n), tree(4 * n + 5), lazy(4 * n + 5) { build(a, 1, 1, n); }

    void update(int i, int l, int r, int ql, int qr) {
        if (l > r || l > qr || r < ql || ql > qr) return;
        if (l >= ql && r <= qr) {
            apply(i, r - l + 1, 1);
            return;
        }
        push(i, l, r);
        int m = (l + r) / 2;
        update(i * 2, l, m, ql, qr);
        update(i * 2 + 1, m + 1, r, ql, qr);
        tree[i] = tree[i * 2] + tree[i * 2 + 1];
    }

    int get(int i, int l, int r, int k) {
        if (l > r || l > k || k > r) return -1; // should be unreachable
        if (l == r) return tree[i];
        push(i, l, r);
        int m = (l + r) / 2;
        if (k <= m) return get(i * 2, l, m, k);
        return get(i * 2 + 1, m + 1, r, k);
    }

    void update(int ql, int qr) { return update(1, 1, n, ql, qr); }

    int get(int k) { return get(1, 1, n, k); }

    int lower_bound(int x) { return first_true(1, n, [&](int i) { return get(i) >= x; }); }

    int upper_bound(int x) { return first_true(1, n, [&](int i) { return get(i) > x; }); }
};

int n, m;

void solve() {
    cin >> n >> m;

    vll h(n + 1);
    FOR(i, 1, n) {
        cin >> h[i];
    }
    sort(all(h));

    SegmentTree st(h, n);
    while (m--) {
        char type;
        int c, h, l, r;
        cin >> type;
        if (type == 'F') {
            cin >> c >> h;
            int s = st.lower_bound(h);
            if (s == n + 1) continue;
            int t = min(s + c - 1, n);
            if (t == n) {
                st.update(s, n);
                continue;
            }
            int x = st.get(t);
            int first = st.lower_bound(x);
            int last = st.upper_bound(x) - 1;
            int delta = c - first + s;
            st.update(s, first - 1);
            st.update(last - delta + 1, last);
        } else {
            cin >> l >> r;
            cout << st.upper_bound(r) - st.lower_bound(l) << el;
        }
    }
}

int main() {
    fast_io
    #define LOCAL
    #ifndef LOCAL
    #define PROBLEM ""
    freopen(PROBLEM ".INP", "r", stdin);
    freopen(PROBLEM ".OUT", "w", stdout);
    #endif

    int t = 1;
    // cin >> t;
    while (t--) solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...