1285E Delete a Segment (扫描线)

传送门
一眼看下来感觉就是线段树,但修了很久才修好.这题有一个很坑的点,不只有线段染色,还有单点染色,所以不能用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;
}    

猜你喜欢

转载自blog.csdn.net/weixin_45590210/article/details/109132122