二分 + 线段树 区间更新(模板)
序列维护
http://www.nowcoder.com/questionTerminal/8f5759df4aaf40a28906dfedf28fbf6d
#include <bits/stdc++.h> using namespace std; class segtree{ public: int n; int* data; int* tree; int* lazy; segtree(int* arr, int _n) : n(_n) { data = new int[_n]; tree = new int[_n * 4]; lazy = new int[_n * 4]; fill_n(tree, _n * 4, 0); fill_n(lazy, _n * 4, 0); for (int i = 0; i < _n; i++) { data[i] = arr[i]; } build(0, 0, n - 1); } ~segtree() { delete []data; delete []tree; delete []lazy; } void push(int tId) { tree[tId] = tree[tId * 2 + 1] + tree[tId * 2 + 2]; } void pull(int tId, int l, int r) { int mid = (l + r) / 2; tree[tId * 2 + 1] += (mid - l + 1) * lazy[tId]; tree[tId * 2 + 2] += (r - mid) * lazy[tId]; lazy[tId * 2 + 1] += lazy[tId]; lazy[tId * 2 + 2] += lazy[tId]; lazy[tId] = 0; } void build(int tId, int l, int r) { if (l == r) { tree[tId] = data[l]; return; } int mid = (l + r) / 2; build(tId * 2 + 1, l, mid); build(tId * 2 + 2, mid + 1, r); push(tId); } int get(int tId, int l, int r, int x) { if (l == r && l == x) { return tree[tId]; } if (lazy[tId]) { pull(tId, l, r); } int mid = (l + r) / 2; if (x <= mid) { return get(tId * 2 + 1, l, mid, x); } else { return get(tId * 2 + 2, mid + 1, r, x); } } void modify(int tId, int l, int r, int ml, int mr, int v) { if (ml <= l && r <= mr) { tree[tId] += (r - l + 1) * v; lazy[tId] += v; return; } if (lazy[tId] != 0) { pull(tId, l, r); } int mid = (l + r) >> 1; if (mr <= mid) { modify((tId * 2) + 1, l, mid, ml, mr, v); } else if (ml > mid) { modify((tId * 2) + 2, mid + 1, r, ml, mr, v); } else { modify((tId * 2) + 1, l, mid, ml, mid, v); modify((tId * 2) + 2, mid + 1, r, mid + 1, mr, v); } push(tId); } }; int arr[234567]; int main() { int n, q; cin >> n >> q; for (int i = 0; i < n; i++) { scanf("%d", &arr[i]); } sort(arr, arr + n); segtree st(arr, n); while (q--) { int x; int l = 0, r = n - 1; scanf("%d", &x); while (l <= r) { int mid = (l + r) >> 1; if (st.get(0, 0, n - 1, mid) < x) l = mid + 1; else r = mid - 1; } if (l >= n) { cout << "0" << "\n"; } else { cout << n - 1 - l + 1 << "\n"; st.modify(0, 0, n - 1, l, n - 1, -1); } } return 0; }