传送门
一眼看下来感觉就是线段树,但修了很久才修好.这题有一个很坑的点,不只有线段染色,还有单点染色,所以不能用i表示i-i+1有线段,不然的话单点染色无法操作.所以只能用i表示点.而维护线段的连通性可以在左右两端加两个标记,lc,rc.lc表示左端有线段连到左边,rc表示右端有线段连到右边.然后在修改的过程中修改这两个标记.
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#define lson(i) tree[i].l
#define rson(i) tree[i].r
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline void read(int &a){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';ch=getchar();}
a = x*f;
}
struct Tree{
int l,r,sum,lc,rc,cover;
}tree[N*20];
int t,n,m,tot,l[N],r[N];
int newnode(){
++tot;tree[tot].l = tree[tot].r = tree[tot].sum = tree[tot].lc = tree[tot].rc = tree[tot].cover = 0;
return tot;
}
void push(int i,int l,int r){
if(!lson(i)) lson(i) = newnode();
if(!rson(i)) rson(i) = newnode();
if(tree[i].cover){
tree[i].sum = 1;
}
else{
tree[i].sum = tree[lson(i)].sum + tree[rson(i)].sum;
if(tree[lson(i)].rc || tree[rson(i)].lc)
tree[i].sum--;
}
}
void add(int &i,int l,int r,int L,int R,int v){
if(!i) i = newnode();
if(l >= L && r <= R){
tree[i].cover += v;
push(i,l,r);
return;
}
push(i,l,r);
int mid = l + r >> 1;
if(R <= mid) add(lson(i),l,mid,L,R,v);
else if(L > mid) add(rson(i),mid+1,r,L,R,v);
else{
add(lson(i),l,mid,L,mid,v),add(rson(i),mid+1,r,mid+1,R,v);
tree[lson(i)].rc += v;
tree[rson(i)].lc += v;
}
push(i,l,r);
}
vi all;
int getpos(int x){
return lower_bound(ALL(all),x) - all.begin();
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin >> t;
while(t--){
int root = 0;
tot = 0;
cin >> n;
all.clear();
all.pb(INT_MIN);
fir(i,1,n){
cin >> l[i] >> r[i];
all.pb(l[i]);all.pb(r[i]);
}
sort(ALL(all));
all.erase(unique(ALL(all)),all.end());
int tn = all.size()-1;
fir(i,1,n){
l[i] = getpos(l[i]);r[i] = getpos(r[i]);
add(root,1,tn,l[i],r[i],1);
}
int ans = 0;
fir(i,1,n){
add(root,1,tn,l[i],r[i],-1);
ans = max(ans,tree[root].sum);
add(root,1,tn,l[i],r[i],1);
}
cout << ans << "\n";
}
return 0;
}