给定n个区间,按顺序覆盖后,问最后几个是可见的。
l,r,范围1e7,需要离散化。
//但是注意简单的离散化可能会出现错误,给出下面两个简单的例子应该能体现普通离散化的缺陷:
//例子一:1-10 1-4 5-10
//例子二:1-10 1-4 6-10
//解决的办法则是对于距离大于1的两相邻点,中间再插入一个点
这样离散化后
例子一:[1,6] [1,3] [4,6]
例子二:[1,7] [1,3] [5,7]
转自 https://www.cnblogs.com/xuejianye/p/5694750.html
#include <cstdio>
#include <iostream>
#include <map>
#include <cstring>
#include <algorithm>
#include <iterator>
#include <vector>
using namespace std;
#define lc (rt << 1)
#define rc (rt << 1 | 1)
#define mid (l + r) / 2
const int maxn = 1e4 + 5;
struct node{
int l,r;
int lid,rid;
}ns[maxn];
map<int,int> mp;
map<int,int>::iterator it,pit;
int N;
int tr[maxn << 4],setv[maxn << 4];
bool vis[maxn];
void init(int l,int r,int rt)//初始设为0,统计时不计入颜色
{
if(l == r){
tr[rt] = setv[rt] = 0;
return ;
}
init(l,mid,lc);
init(mid + 1,r,rc);
tr[rt] = setv[rt] = 0;
}
void pushdown(int l,int r,int rt)
{
if(setv[rt]){
setv[lc] = setv[rc] = setv[rt];
tr[lc] = tr[rc] = setv[rt];
setv[rt] = 0;
}
}
void update(int ql,int qr,int l,int r,int rt,int x)
{
// printf("in update %d %d %d %d %d\n",ql,qr,l,r,x);
if(ql <= l && r <= qr){
tr[rt] = x;
setv[rt] = x;
return ;
}
pushdown(l,r,rt);
if(ql <= mid) update(ql,qr,l,mid,lc,x);
if(mid < qr) update(ql,qr,mid + 1,r,rc,x);
}
int query(int p,int l,int r,int rt)
{
if(l == r) return tr[rt];
pushdown(l, r, rt);
if(p <= mid) return query(p, l, mid, lc);
return query(p, mid + 1, r, rc);
}
int main()
{
int T;scanf("%d",&T);
int n;
while(T --){
scanf("%d",&n);
mp.clear();
memset(vis,0,sizeof(vis));
for(int i = 1;i <= n;i ++){
scanf("%d%d",&ns[i].l,&ns[i].r);
// if(ns[i].l > ns[i].r || ns[i].l < 1 || ns[i].r > 10000000) continue;
mp[ns[i].l];mp[ns[i].r];
}
it = mp.begin();pit = it;it ++;
vector<int> v;
while(it != mp.end()){
if(it->first - pit->first > 1) v.push_back(pit->first + 1);
pit = it;it ++;
}
for(int i = 0;i < v.size();i ++) mp[v[i]];
int p = 1;
it = mp.begin();
while(it != mp.end()) {it->second = p ++;it ++;}
N = p ;
init(1, N, 1);
// cout << "N = " << N << endl;
for(int i = 1;i <= n;i ++){
ns[i].lid = mp[ns[i].l];
ns[i].rid = mp[ns[i].r];
// printf("%d -> %d\n",ns[i].l,ns[i].lid);
// printf("%d -> %d\n",ns[i].r,ns[i].rid);
}
for(int i = 1;i <= n;i ++){
update(ns[i].lid ,ns[i].rid,1,N,1,i);
// printf("update %d %d \n",ns[i].lid,ns[i].rid);
}
for(int i = 1;i <= N;i ++){
int t = query(i,1,N,1);
// printf("at %d c = %d\n",i,t);
vis[t] = 1;
}
int ans = 0;
for(int i = 1;i <= n;i ++) if(vis[i]) ans ++;
printf("%d\n",ans);
}
return 0;
}