LC 3479(2100) 线段树二分 水果成篮

题目
题目:
给你两个长度为 n 的整数数组,fruits 和 baskets,其中 fruits[i] 表示第 i 种水果的 数量,baskets[j] 表示第 j 个篮子的 容量。
你需要对 fruits 数组从左到右按照以下规则放置水果:
每种水果必须放入第一个 容量大于等于 该水果数量的 最左侧可用篮子 中。
每个篮子只能装 一种 水果。
如果一种水果 无法放入 任何篮子,它将保持 未放置。
返回所有可能分配完成后,剩余未放置的水果种类的数量。

思路:
我们需要应用一种数据和结构,可以高效地进行区间查询(查找最左边的符合条件的篮子)和更改(一个篮子装完水果后就没用了) ,那么显然是线段树。
直接套用线段树模板即可,注意下标。

代码:

const int MAXN = 1e5+2;
int tree[MAXN * 4];
const int inf = 1e9;
class Solution {
public:
    int numOfUnplacedFruits(vector<int>& fruits, vector<int>& baskets) {
        int n = fruits.size();
        auto build = [&](this auto&& self, int x, int l, int r) {
            if (l == r) {
                tree[x] = baskets[l - 1];
                return;
            }

            int mid = (l + r) >> 1;
            self(x * 2, l, mid);
            self(x * 2 + 1, mid + 1, r);
            tree[x] = max(tree[x * 2], tree[x * 2 + 1]);
        };

        auto change = [&](this auto &&self, int x, int l, int r, int cp, int cv) {
            if (l > cp || r < cp) return;
            if (l == r) {
                tree[x] = cv;
                return;
            }

            int mid = (l + r) >> 1;
            if (cp <= mid) self(x * 2, l, mid, cp, cv);
            else self(x * 2 + 1, mid + 1, r, cp, cv);

            tree[x] = max(tree[x * 2], tree[x * 2 + 1]);
        };

        auto query = [&](this auto&& self, int x, int l, int r,  int qv) {
            if (tree[x] < qv) return -1;
            if (l == r) return l;
            int mid = (l + r) >> 1;
            if (tree[x * 2] >= qv) {
                int q = self(x * 2, l, mid, qv);
                if (q >= 0) return q;
            }
            return self(x * 2 + 1, mid + 1, r, qv);

        };
        build(1, 1, n);
        
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            int k = query(1, 1, n, fruits[i]);
            if (k < 0) {
                ans++;
            }
            else {
                change(1, 1, n, k, -inf);
            }
        }
        return ans;


    }
};
posted @ 2025-12-03 20:04  Wuyou2008  阅读(2)  评论(0)    收藏  举报