fi 表示当前选的点覆盖了 1到i 区间(已对区间排序),后面区间都没覆盖的最大数量。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 4e5+100;
int n,m;
struct node
{
int l1,r1,mi=1e18,mx;
}tr[N*4];
namespace sg
{
int cnt=1;
#define ll (tr[x].l1)
#define rr (tr[x].r1)
#define mid ((l+r)>>1)
#define xx (tr[x])
void build(int x,int l,int r)
{
if(l==r)
{
xx.mi=1e18,xx.mx=0;
return;
}
ll=++cnt;
rr=++cnt;
build(ll,l,mid);
build(rr,mid+1,r);
xx.mi=1e18;
}
void addm(int l1,int r1,int x,int l,int r,int mi)
{
if(l>=l1&&r<=r1)
{
xx.mi=min(xx.mi,mi);
return;
}
if(l1<=mid)
{
addm(l1,r1,ll,l,mid,mi);
}
if(r1>mid)
{
addm(l1,r1,rr,mid+1,r,mi);
}
}
void add(int l1,int r1,int x,int l,int r,int mx)
{
if(l>=l1&&r<=r1)
{
xx.mx=max(xx.mx,mx);
return;
}
if(l1<=mid)
{
add(l1,r1,ll,l,mid,mx);
}
if(r1>mid)
{
add(l1,r1,rr,mid+1,r,mx);
}
}
int find(int pos,int x,int l,int r)
{
int res=xx.mx;
if(l==r)
{
return res;
}
if(pos<=mid)
{
return max(res,find(pos,ll,l,mid));
}
else
{
return max(res,find(pos,rr,mid+1,r));
}
}
int findm(int pos,int x,int l,int r)
{
int res=xx.mi;
if(l==r)
{
return res;
}
if(pos<=mid)
{
return min(res,findm(pos,ll,l,mid));
}
else
{
return min(res,findm(pos,rr,mid+1,r));
}
}
#undef ll
#undef rr
#undef mid
#undef xx
}
using namespace sg;
int ans,nxt[N];
int f[N];
struct seg
{
int l,r;
}s[N];
bool operator <(seg x,seg y)
{
if(x.r!=y.r)return x.r<y.r;
return x.l<y.l;
}
int find(int x)
{
if(nxt[x]!=x)return nxt[x]=find(nxt[x]);
return nxt[x];
}
signed main()
{
cin>>n>>m;
int l,r;
build(1,1,n);
for(int i=1;i<=m;i++)
{
cin>>l>>r;
s[i]={l,r};
}
sort(s+1,s+1+m);
for(int i=1;i<=m;i++)
{
add(s[i].l,s[i].r,1,1,n,i);
addm(s[i].l,s[i].r,1,1,n,i);
}
memset(f,0xcf,sizeof f);
f[0]=0;
for(int i=1;i<=n;i++)
{
l=find(i,1,1,n);
r=findm(i,1,1,n);
if(r==1e18)
{
ans++;
}
else
{
f[l]=max(f[l],f[r-1]+1);
}
}
// ans=0;
if(f[m]>=0)cout<<ans+f[m];
else
{
cout<<"-1";
}
}