Submission #1309881

#TimeUsernameProblemLanguageResultExecution timeMemory
1309881buzdiGrowing Trees (BOI11_grow)C++17
100 / 100
77 ms2416 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define ll long long

using namespace std;
using namespace __gnu_pbds;

const int NMAX = 1e5;

int n, m;
int a[NMAX + 1];

struct AIB {
    int n;
    int aib[NMAX + 1];

    void init(int n) {
        this->n = n;
        fill(aib + 1, aib + n + 1, 0);
    }

    void update(int pos, int value) {
        for(int i = pos; i <= n; i += i & (-i)) {
            aib[i] += value;
        }
    }

    void update(int l, int r, int value) {
        update(l, value);
        update(r + 1, -value);
    }

    int query(int pos) {
        int answer = 0;
        for(int i = pos; i >= 1; i -= i & (-i)) {
            answer += aib[i];
        }
        return answer;
    }
}aib;

int first_greater(int start, int value) {
    int left = start, right = n, answer = n + 1;
    while(left <= right) {
        int mid = (left + right) / 2;
        if(aib.query(mid) >= value) {
            answer = mid;
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return answer;
}

void update(int c, int h) {
    int l = first_greater(1, h);
    if(l == n + 1) {
        return;
    }

    int r = l + c - 1;
    if(r >= n) {
        aib.update(l, n, 1);
        return;
    }

    int last_value = aib.query(r);
    int first_pos_last = first_greater(l, last_value);
    int last_pos_last = first_greater(l, last_value + 1) - 1;
    int adding_left = first_pos_last - l;
    int adding_right = c - adding_left;

    aib.update(l, first_pos_last - 1, 1);
    aib.update(last_pos_last - adding_right + 1, last_pos_last, 1);
}

int query(int l, int r) {
    return first_greater(1, r + 1) - first_greater(1, l);
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    sort(a + 1, a + n + 1);

    aib.init(n);
    for(int i = 1; i <= n; i++) {
        aib.update(i, i, a[i]);
    }

    while(m--) {
        char type;
        int x, y;
        cin >> type >> x >> y;
        if(type == 'F') {
            update(x, y);
        }
        else {
            cout << query(x, y) << '\n';
        }
    }
    return 0;
}
#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...