厦门建网站多少钱网站排名优化的技巧
这个题就是线段树的应用,但是与之前的文章相比,此处构建的线段树相当于“最大树”,每个节点存储的不是子节点的和,而是子节点中的最大值。
#include <bit>
class SegmentTree {vector<int> mx;void maintain(int o) {// 根据不同的线段树的需求修改对应的代码,// 本题需要找到最左边最大的点,因此需要构建最大线段树mx[o] = max(mx[o * 2], mx[o * 2 + 1]);}void build(const vector<int>& a, int o, int l, int r) {if(l == r) {mx[o] = a[l];return;}int m = (l + r) / 2;build(a, o * 2, l, m);build(a, o * 2 + 1, m + 1, r);maintain(o);}public:SegmentTree(const vector<int>& a) {size_t n = a.size();mx.resize(2 << bit_width(n - 1));build(a, 1, 0, n - 1);}int findFirstAndUpdate(int o, int l, int r, int x) {if(mx[o] < x) {return -1;}if(l == r) {mx[o] = -1;return l;}int m = (l + r) / 2;int i = findFirstAndUpdate(o * 2, l, m, x);if(i < 0) {i = findFirstAndUpdate(o * 2 + 1, m + 1, r, x);}// 注意更新线段树上部的信息maintain(o);return i;}
};class Solution {
public:int numOfUnplacedFruits(vector<int>& fruits, vector<int>& baskets) {SegmentTree t(baskets);int n = baskets.size(), result = 0;for(auto x : fruits) {if(t.findFirstAndUpdate(1, 0, n - 1, x) < 0) {result++;}}return result;}
};
注意此处就涉及到之前说的那个s + t 会溢出的问题,因此不能用移位操作来实现。