// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to build a segment tree
void build(vector<int>& sum,
vector<int>& a,
int l, int r, int rt)
{
// Check for base case
if (l == r) {
sum[rt] = a[l - 1];
return;
}
// Find mid point
int m = (l + r) >> 1;
// Recursively build the
// segment tree
build(sum, a, l, m, rt << 1);
build(sum, a, m + 1, r, rt << 1 | 1);
}
// Function for push down operation
// on the segment tree
void pushDown(vector<int>& sum,
vector<int>& add,
int rt, int ln, int rn)
{
if (add[rt]) {
add[rt << 1] += add[rt];
add[rt << 1 | 1] += add[rt];
sum[rt << 1] += add[rt] * ln;
sum[rt << 1 | 1] += add[rt] * rn;
add[rt] = 0;
}
}
// Function to update the segment tree
void update(vector<int>& sum,
vector<int>& add,
int L, int R, int C, int l,
int r, int rt)
{
// Complete overlap
if (L <= l && r <= R) {
sum[rt] += C * (r - l + 1);
add[rt] += C;
return;
}
// Find mid
int m = (l + r) >> 1;
// Perform push down operation
// on segment tree
pushDown(sum, add, rt, m - l + 1,
r - m);
// Recursively update the segment tree
if (L <= m)
update(sum, add, L, R, C, l, m,
rt << 1);
if (R > m)
update(sum, add, L, R, C, m + 1, r,
rt << 1 | 1);
}
// Function to process the query
int query(vector<int>& sum,
vector<int>& add,
int L, int R, int l,
int r, int rt)
{
// Base case
if (L <= l && r <= R) {
return sum[rt];
}
// Find mid
int m = (l + r) >> 1;
// Perform push down operation
// on segment tree
pushDown(sum, add, rt, m - l + 1,
r - m);
int ans = 0;
// Recursively calculate the result
// of the query
if (L <= m)
ans += query(sum, add, L, R, l, m,
rt << 1);
if (R > m)
ans += query(sum, add, L, R, m + 1, r,
rt << 1 | 1);
// Return the result
return ans;
}
// Function to count the numbers
// which are greater than the given query
void sequenceMaintenance(int n, int q,
vector<int>& a,
vector<int>& b,
int m)
{
// Sort the input array
sort(a.begin(), a.end());
// Create segment tree of size 4*n
vector<int> sum, add, ans;
sum.assign(n << 2, 0);
add.assign(n << 2, 0);
// Build the segment tree
build(sum, a, 1, n, 1);
// Iterate over the queries
for (int i = 0; i < q; i++) {
int l = 1, r = n, pos = -1;
while (l <= r) {
int m = (l + r) >> 1;
if (query(sum, add, m, m, 1, n, 1)
>= b[i]) {
r = m - 1;
pos = m;
}
else {
l = m + 1;
}
}
if (pos == -1)
ans.push_back(0);
else {
// Store result in array
ans.push_back(n - pos + 1);
// Update the elements in
// the given range
update(sum, add, pos, n, -m,
1, n, 1);
}
}
// Print the result of queries
for (int i = 0; i < ans.size(); i++) {
cout << ans[i] << " ";
}
}
// Driver Code
int main()
{
int N = 4;
int Q = 3;
int M = 1;
vector<int> arr = { 1, 2, 3, 4 };
vector<int> query = { 4, 3, 1 };
// Function Call
sequenceMaintenance(N, Q, arr, query, M);
return 0;
}