思路

典型的区间染色问题。
离散化区间端点(注意非连续区间中间要加点隔开),就可以建线段树了。
倒序每一次询问,查看该区间是否被覆盖,如果没有就ans++,然后顺便把区间覆盖掉。

代码

#include<iostream>
#include<vector>
#include<algorithm>
#define MID int mid=(p->l + p->r)>>1
using namespace std;
struct Post{ // 海报
    int l,r;
} pst[10100];
int nodenum,cnt,ans;
int t,n,hs[10000010];
vector<int>vt;

struct Node{
    int l,r;
    bool full; // 区间[l,r]是否被完全覆盖
    Node *ls, *rs; 
}tr[1000000];

void buildTree(Node *p, int l, int r){ //建树 
    p->l=l;
    p->r=r;
    p->full=0; //初始化节点 
    if(l==r)return; //如果是叶子,直接返回 
    nodenum++;
    p->ls=tr+nodenum; //建立左右子树 
    nodenum++;
    p->rs=tr+nodenum;
    MID;
    buildTree(p->ls,l,mid); //左区间建树 
    buildTree(p->rs,mid+1,r); //右区间建树 
}
bool check(Node *p,int l,int r){ //判断该区间是否有覆盖 
    if (p->full) return false; //已经被覆盖了,这份海报就看不到了 
    if (p->l==l&&p->r==r){
        p->full=1; //覆盖此区间 
        return true;
    }
    bool res;
    MID;
    if(r<=mid) res=check(p->ls,l,r); //全在左区间,找左子树 
    else if(l>mid) res=check(p->rs,l,r);
    else{
        bool b1=check(p->ls,l,mid);
        bool b2=check(p->rs,mid+1,r);
        res=b1||b2; //其中一点没覆盖即可 
    }
    if (p->ls->full&&p->rs->full){
        p->full=1;//如果左右区间都被覆盖,那么这个区间也被覆盖了 
    }
    return res;
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n;
        nodenum=0,cnt=0,ans=0; //清空数据 
        for(int i=0;i<n;i++) {
            cin>>pst[i].l>>pst[i].r;
            vt.push_back(pst[i].l); //把区间端点放入容器 
            vt.push_back(pst[i].r);
        }
        sort(vt.begin(),vt.end());//排序 
        vt.erase(unique(vt.begin(),vt.end()),vt.end()); //去重 
        for(int i=0;i<vt.size();i++){
            hs[vt[i]]=cnt++; //记录元素所在数的节点编号 
            if(i<vt.size()-1){
                if(vt[i+1]-vt[i]>1) cnt++; //中间再插一个点 
            }
        } 
        buildTree(tr,0,cnt);//开始建树 
        for(int i=n-1;i>=0;i--){ //这里倒序,要从没被覆盖的开始数 
            if(check(tr,hs[pst[i].l],hs[pst[i].r])){
                ans++; //可见海报增加 
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}