# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1213446 | orzorzorz | Growing Trees (BOI11_grow) | C++20 | 0 ms | 0 KiB |
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ff first
#define ss second
#define all(x) x.begin(), x.end()
const int mxN=1e5+1;
ll bit[mxN+1], a[mxN+1];
int n, m;
void upd(int pos, ll val) {
for(; pos<=mxN; pos+=pos&-pos) {
bit[pos]+=val;
}
}
ll qry(int pos) {
ll res=0;
for(; pos; pos-=pos&-pos) {
res+=bit[pos];
}
return res;
}
int firstTrue(int lo, int hi, function<bool(int)> pred) {
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (pred(mid)) hi = mid;
else lo = mid + 1;
}
return lo;
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
cin>>n>>m;
for(int i=1; i<=n; i++) {
cin>>a[i];
}
sort(a+1, a+n+1);
for(int i=1; i<=n; i++) {
upd(i, a[i]);
upd(i+1, -a[i]);
}
for(int i=0; i<m; i++) {
char ty; cin>>ty;
if (ty == 'F') {
int c, h; cin >> c >> h;
int left = f(h);
if (left == n + 1) continue;
int right = left + c - 1;
if (right > n) {
upd(left, 1);
upd(n + 1, -1);
} else {
ll val = qry(right);
// If no duplicates, update [left, right]
if (qry(right) != qry(right + 1)) {
upd(left, 1);
upd(right + 1, -1);
} else {
// Find range of duplicates
int l_ = firstTrue(left, n, [&](int i) { return qry(i) >= val; });
int r_ = firstTrue(l_, n, [&](int i) { return qry(i) > val; }) - 1;
int to_update = c;
// Update trees before duplicates
if (l_ > left) {
int count = min(to_update, l_ - left);
upd(left, 1);
upd(left + count, -1);
to_update -= count;
}
// Update suffix of duplicates if needed
if (to_update > 0) {
int start = max(l_, r_ - to_update + 1);
if (start <= r_) {
upd(start, 1);
upd(r_ + 1, -1);
}
}
}
}
}
}
return 0;
}
//rating below 2400 must be solved orzorzorz