#include <bits/stdc++.h>
using namespace std;
using ll = long long;
static const int NMAX = 100000 + 1;  // 100000 樹+1,方便做到 n+1
// 全域變數
ll bit[NMAX + 5];  // 差分 / Fenwick Tree
ll a[NMAX + 5];    // 排序後的樹高
int n, m;
// 在 Fenwick Tree 上做「單點加值」
void upd(int pos, ll val) {
    // pos 可能等於 n+1,但不超過 NMAX
    for (; pos <= NMAX; pos += pos & -pos) {
        bit[pos] += val;
    }
}
// Fenwick Tree 的 prefix sum:回傳差分陣列到 pos 的累積和
ll qry(int pos) {
    ll res = 0;
    for (; pos > 0; pos -= pos & -pos) {
        res += bit[pos];
    }
    return res;
}
// 透過二元搜尋,找出最小的 index i,使得 qry(i) ≥ val
// 若沒有人高度 ≥ val,就回傳 n+1
int f(ll val) {
    int l = 1, r = n, ans = n + 1;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (qry(mid) >= val) {
            ans = mid;
            r = mid - 1;
        } else {
            l = mid + 1;
        }
    }
    return ans;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    // 1) 把初始樹高排序
    sort(a + 1, a + n + 1);
    // 2) 我們視 a[0] = 0(代表第 0 個位置的高度 0),
    //    然後建立差分陣列 d[i] = a[i] - a[i-1],並放進 Fenwick Tree
    a[0] = 0;
    for (int i = 1; i <= n; i++) {
        ll diff = a[i] - a[i - 1];
        // 差分: 在 i 開始 +diff,在 i+1 開始 -diff
        // 但因為我們只需要「差分型 Fenwick Tree」來做區間加&單點查,
        // 直接用 upd(i, diff);upd(i+1, -diff) 來構造原始高度 a[i]。
        upd(i, diff);
        upd(i + 1, -diff);
    }
    // 3) 處理 m 筆操作
    while (m--) {
        char ty;
        cin >> ty;
        if (ty == 'F') {
            // 「F c h」── 找到 c 棵最矮、且高度 ≥ h 的樹,各自 +1
            int c;
            ll h;
            cin >> c >> h;
            // (1) left = f(h) → 第一棵高度 ≥ h 的索引
            int left = f(h);
            if (left == n + 1) {
                // 沒有任何樹 ≥ h,直接跳過
                continue;
            }
            // (2) right = left + c - 1
            int right = left + c - 1;
            if (right > n) {
                // 如果超過 n,代表所有剩下的樹都要 +1
                upd(left,     1);
                upd(n + 1,   -1);
                continue;
            }
            // (3) 如果 a[right] < a[right+1],我們可以一次把 [left..right] 全 +1
            //    注意 a[i] = qry(i) 給出第 i 棵樹當前的高度
            if (qry(right) != qry(right + 1)) {
                // safe to do whole interval
                upd(left,      1);
                upd(right + 1, -1);
                continue;
            }
            // (4) 否則表示 a[right] == a[right+1],也就是卡在同一個 equal‐group 中間
            ll val = qry(right);        // 這群 equal‐group 的高度
            int newl = f(val);          //  equal‐group 起點 index
            int newr = f(val + 1);      //  equal‐group 結尾 + 1
            // (4a) 先把 [left..newl-1](這些高度 < val)的樹全部 +1
            if (left <= newl - 1) {
                upd(left,      1);
                upd(newl,    -1);
            }
            // (4b) 再把 equal‐group 裡「真正要 +1 的 [newl..right]」各 +1
            upd(newl,        1);
            upd(right + 1,  -1);
        }
        else {
            // ty == 'C':查詢「高度在 [x..y] 之間」有多少棵樹
            ll x, y;
            cin >> x >> y;
            // l = f(x) → 第一棵高度 ≥ x 的索引
            // r = f(y+1) → 第一棵高度 ≥ y+1 的索引
            int l = f(x);
            int r = f(y + 1);
            if (l == n + 1) {
                // 如果找不到高度 ≥ x,則都小於 x,答案 = 0
                cout << 0 << "\n";
            } else {
                // r = n+1 表示所有都 ≤ y;所以有效區間 [l..n]
                if (r == n + 1) {
                    r = n;
                } else {
                    // r 是第一個高度 ≥ y+1 的索引,要排除
                    r = r - 1;
                }
                if (r < l) {
                    cout << 0 << "\n";
                } else {
                    cout << (r - l + 1) << "\n";
                }
            }
        }
    }
    return 0;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |