二分 + 线段树 区间更新(模板)
序列维护
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;
}