本题注意离散化的时候可能会出现区间串联情况,比如
[1,10] [5,10] [1,4] 和 [1,10] [6,10] [1,4] 直接离散化的话两者一样,但是实际上是不一样的
解决办法是你在相邻的差不是1的数对中再插一个数就好了
离线区间染色 查询根节点
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e5+10,inf = 0x3f3f3f3f;
struct Segment{
int l,r;
int id;
}tr[N<<3];
bool st[N];
vector<int>v;
vector< pair<int,int> >op;
int m;
int findx(int x){return lower_bound(v.begin(),v.end(),x)-v.begin();}
void pushdown(int u){
if(tr[u].id){
tr[u<<1].id = tr[u<<1|1].id = tr[u].id;
tr[u].id = 0;
}
}
void build(int u,int l,int r){
tr[u] = {l,r,0};
if(l==r)return;
int mid = l+r>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
}
void modify(int u,int l,int r,int c){
if(tr[u].l>=l&&tr[u].r<=r){tr[u].id = c;return;}
pushdown(u);
int mid = tr[u].l+tr[u].r>>1;
if(l<=mid)modify(u<<1,l,r,c);
if(r>mid)modify(u<<1|1,l,r,c);
}
int query(int u){
if(tr[u].id){
if(st[tr[u].id])return 0;
return st[tr[u].id] = 1;
}
if(tr[u].l==tr[u].r)return 0;
return query(u<<1)+query(u<<1|1);
}
int main()
{
int _;cin>>_;
while(_--){
v.clear(),op.clear();v.push_back(-inf),op.push_back({0,0});
memset(st,0,sizeof st);
cin>>m;
for(int i=1;i<=m;++i){
int l,r;cin>>l>>r;
v.push_back(l),v.push_back(r);
op.push_back({l,r});
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
int vlen = v.size();
for(int i=1;i+1<vlen;++i)if(v[i+1]-v[i]>1)v.push_back(v[i+1]-1);
sort(v.begin(),v.end());
build(1,1,v.size()-1);
for(int i=1;i<=m;i++){
int l = findx(op[i].first),r =findx(op[i].second);
modify(1,l,r,i);
}
cout<<query(1)<<"\n";
}
}