一个板子题.不过看评论那么多O(n^2)的解法...反正我用O(n^2)试了试..没过...
其实二分套线段树还挺常见的.
不过因为长时间没写过题了..我线段树板子都快忘了,花了一个多小时才回忆起来...
下面是思路:
由于是将所有>=x的数减一.所以我们很容易想到线段树的区间修改和区间查询.
但是值修改之后我们如何确定第一个>=x的位置呢?
通过二分,首先将数组排序,因为修改的限制,所以数组只会是一个不减的数组.
那么我们就可以二分位置,确定一个位置pos是第一个>=x的位置,
    然后如果这个位置>n,就说明没有一个元素符合条件.    
    否则输出n-l+1.然后更新线段树即可.
还是比较好想的,注意一下线段树的实现(退役选手4个月不刷题流下了菜鸡的眼泪QAQ)
当然,这个题目可能有更好的方法,但我限于智商和水平,只有这个一般解法了QAQ.
ACCode:
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
// srand((unsigned)time(NULL));rand();
      
#include<map>//unordered_map
#include<set>//multiset
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
 
#define ll long long
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
      
const int MAXN=2e5+10;
//const int MAXM=10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)

class SegTree{
	struct Node{
		int sum;
		int l,r,len;
		int lazy;
	};
	Node T[MAXN<<2];
	
	void PushUp(int rt){
		T[rt].sum=T[rt<<1].sum+T[rt<<1|1].sum;
	} 
	void PushDown(int rt){
		if(T[rt].lazy!=0){
			T[rt<<1].lazy+=T[rt].lazy;
			T[rt<<1|1].lazy+=T[rt].lazy;
			T[rt<<1].sum+=T[rt<<1].len*T[rt].lazy;
			T[rt<<1|1].sum+=T[rt<<1|1].len*T[rt].lazy;
			T[rt].lazy=0;
		}
	}
	public:
	void Build(int l,int r,int rt,int A[]){
		T[rt].l=l;T[rt].r=r;T[rt].len=r-l+1;
		T[rt].lazy=0;
		if(l==r){
			T[rt].sum=A[l];
			return ;
		}int mid=(l+r)>>1;
		Build(l,mid,rt<<1,A);Build(mid+1,r,rt<<1|1,A);
		PushUp(rt);
	}
	int Query(int x,int rt){
		if(T[rt].l==T[rt].r) return T[rt].sum;
		PushDown(rt);
		if(T[rt<<1].r>=x) return Query(x,rt<<1);
		else return Query(x,rt<<1|1);
	}
	void Update(int ql,int qr,int x,int rt){
//		printf("l=%d r=%d ql=%d qr=%d\n",T[rt].l,T[rt].r,ql,qr);
		if(ql<=T[rt].l&&qr>=T[rt].r){
			T[rt].lazy+=x;
			T[rt].sum+=T[rt].len*x;
			return ;
		}PushDown(rt);
		if(qr<=T[rt<<1].r) Update(ql,qr,x,rt<<1);
		else if(ql>=T[rt<<1|1].l) Update(ql,qr,x,rt<<1|1);
		else{
			Update(ql,qr,x,rt<<1);Update(ql,qr,x,rt<<1|1);
		}
	}
	void Show(int rt){
		printf("l=%d r=%d T[rt].sum=%d\n",T[rt].l,T[rt].r,T[rt].sum);
		if(T[rt].l==T[rt].r) return ;
		PushDown(rt);
		Show(rt<<1);Show(rt<<1|1);
	}
};

int A[MAXN];
SegTree st;

int main(){
	int n,q;scanf("%d%d",&n,&q);
	int mx=0;
	for(int i=1;i<=n;++i){
		int x;scanf("%d",&A[i]);
		mx=max(mx,x);
	}sort(A+1,A+1+n);st.Build(1,n,1,A);
	while(q--){
		int x;scanf("%d",&x);
		int l=1,r=n,mid;
		while(l<=r){
			mid=(l+r)>>1;
			int xx=st.Query(mid,1);
//			printf("xx=%d  x=%d\n",xx,x);
			if(st.Query(mid,1)<x) l=mid+1;
			else r=mid-1;
		}
//		printf("l=%d\n",l);
		if(l>n) printf("0\n");
		else{
			printf("%d\n",n-l+1);
			st.Update(l,n,-1,1);
		}//st.Show(1);
	}
}