題意: 求不相交的區間集合,沒有覆蓋到的範圍最小
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 4e5+10;
const int M = 26;
const int INF = 0x3f3f3f3f;
vector<LL> xs;
inline int getid(LL x){return lower_bound(xs.begin(),xs.end(), x) - xs.begin() + 1;}
struct asd{
LL l,r;
LL sum;
}a[N];
bool cmp(asd x,asd y){
if(x.l != y.l) return x.l < y.l;
return x.r < y.r;
}
struct Node{
int left,right;
LL maxn;
}node[N*4];
int father[N*4];
void BulitTree(int i,int l,int r){
node[i].left = l;
node[i].right = r;
node[i].maxn = 0;
if(l == r){
father[l] = i;
return ;
}
BulitTree(i*2,l,(l+r)/2);
BulitTree(i*2+1,(l+r)/2+1,r);
}
void Update(int i){
if(i == 1) return ;
int pi = i/2;
LL x = node[pi*2].maxn;
LL y = node[pi*2+1].maxn;
node[pi].maxn = max(x,y);
Update(pi);
}
LL ans;
void Query(int i,int l,int r){
if(node[i].right==r && node[i].left==l){
ans = max(ans,node[i].maxn);
return ;
}
i = i*2;
if(l <= node[i].right){
if(r <= node[i].right){
Query(i,l,r);
}
else{
Query(i,l,node[i].right);
}
}
i++;
if(r >= node[i].left){
if(l >= node[i].left)
Query(i,l,r);
else
Query(i,node[i].left,r);
}
}
int main(){
LL n;
int m;
scanf("%lld%d",&n,&m);
BulitTree(1,1,m*2+1);
for(int i = 1; i <= m; i++){
scanf("%I64d%I64d",&a[i].l,&a[i].r);
a[i].sum = a[i].r-a[i].l+1;
}
sort(a+1,a+m+1,cmp);
xs.push_back(0);
for(int i = 1; i <= m; i++)
{
xs.push_back(a[i].l);
xs.push_back(a[i].r);
}
sort(xs.begin(), xs.end());
vector<LL>::iterator e;
e=unique(xs.begin(),xs.end());
xs.erase(unique(xs.begin(), xs.end()) , xs.end());
int id = getid(0);
int x = father[id];
node[x].maxn = 0;
Update(x);
for(int i = 1; i <= m; i++){
id = getid(a[i].l);
ans = 0;
Query(1,1,id-1);
id = getid(a[i].r);
x = father[id];
node[x].maxn = ans+a[i].sum;
Update(x);
}
ans = 0;
Query(1,1,m*2+1);
printf("%I64d\n",n-ans);
return 0;
}