恩,我觉得这也是个贪心题。没想出来,菜呀qaq
从小到大考虑一个数,他被若干区间包含,我们一定是把它分配给区间右端点最小的那个区间。这样肯定不会更差。因为剩下的区间的可选择空间更大。
我们考虑把区间按右端点为第一关键字,左端点为第二关键字升序排序,每次对于一个区间我们取离他左端点最近的可选择点和他配对。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 20010
inline char gc(){
static char buf[1<<16],*S,*T;
if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int n,m,ans=0;
struct seg{
int l,r;
friend bool operator<(seg a,seg b){return a.r==b.r?a.l<b.l:a.r<b.r;}
}a[N];
multiset<int>st;multiset<int>::iterator it;
int main(){
// freopen("a.in","r",stdin);
n=read();m=read();
for(int i=1;i<=n;++i) st.insert(read());
for(int i=1;i<=m;++i) a[i].l=read(),a[i].r=read();
sort(a+1,a+m+1);
for(int i=1;i<=m;++i){
it=st.lower_bound(a[i].l);
if(it==st.end()||*it>a[i].r) continue;++ans;st.erase(it);
}printf("%d\n",ans);
return 0;
}