Codeforces Round #483 (Div. 1) D. Arkady and Rectangles 扫描线 线段树套平衡树

Statement
Solution cf offered

这个题要求解最后的颜色数
显然二维线段树可以选择,但是空间过大
那我们应该如何进行维护呢

考虑扫描线
对于非扫描的一维维护线段树
由于颜色很多,在扫描线上又要支持删除,所以考虑对颜色的集合进行维护
每个节点保存这个区间是否被完全覆盖、可以用来更新答案的最大颜色是哪个、最小的裸露在外的颜色是哪个
可以用平衡树维护这个集合从而进行节点信息的更新

#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<map>
#include<set>
using namespace std;

typedef double db;
typedef long long ll;

inline int read()
{
    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=10*x+ch-'0';ch=getchar();}
    return x*f;
}
void print(int x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}

const int N=200100;

int n;

int L[N],R[N],U[N],D[N];

namespace hsh_map
{
    int tot,X[N],Y[N];

    int binary_search(int *a,int x)
    {
        int l(1),r(tot),mid;
        while(l<=r)
        {
            mid=(l+r)>>1;
            a[mid]<=x ? l=mid+1 : r=mid-1;
        }
        return l-1;
    }

    void Main()
    {
        register int i;
        for(i=1;i<=n;++i)
            X[++tot]=L[i],Y[tot]=D[i],
            X[++tot]=R[i],Y[tot]=U[i];
        sort(X+1,X+1+tot),sort(Y+1,Y+1+tot);
        for(i=1;i<=n;++i)
            L[i]=binary_search(X,L[i]),R[i]=binary_search(X,R[i]),
            D[i]=binary_search(Y,D[i]),U[i]=binary_search(Y,U[i]);
    }
}

struct node
{
    set<int> st[2];
    int top[2],cover,mx_remain,mn_cover;

    node(){top[0]=top[1]=cover=mx_remain=mn_cover=-1;}

    void erase(int x)
    {st[0].erase(x),st[1].erase(x);}

    void insert(int x)
    {st[0].insert(x);}

    void move(int x)
    {st[0].erase(x),st[1].insert(x);}

    void update()
    {
        top[0]=st[0].size() ? *st[0].rbegin() : -1;
        top[1]=st[1].size() ? *st[1].rbegin() : -1;
        cover=max(top[0],top[1]);
    }

}v[N<<2];
// vertex

inline void pushup(int k,int l,int r)
{
    if(l==r)
    {
        v[k].mn_cover=v[k].cover,
        v[k].mx_remain=v[k].top[0]>v[k].top[1] ? v[k].top[0] : -1;
        return ;
    }
    int ls=k<<1,rs=k<<1|1;
    v[k].mn_cover=max(v[k].cover,min(v[ls].mn_cover,v[rs].mn_cover));
    v[k].mx_remain=max(v[k].top[0],max(v[ls].mx_remain,v[rs].mx_remain));
    if(v[k].mx_remain<v[k].mn_cover) v[k].mx_remain=-1;
}

void insert(int k,int l,int r,int x,int y,int val)
{
    if(x<=l && y>=r)
    {
        v[k].insert(val);
        v[k].update();
        pushup(k,l,r);
        return ;
    }
    int mid=(l+r)>>1;
    if(x<=mid) insert(k<<1,l,mid,x,y,val);
    if(y>mid) insert(k<<1|1,mid+1,r,x,y,val);
    pushup(k,l,r);
}

void del(int k,int l,int r,int x,int y,int val)
{
    if(x<=l && y>=r)
    {
        v[k].erase(val);
        v[k].update();
        pushup(k,l,r);
        return ;
    }
    int mid=(l+r)>>1;
    if(x<=mid) del(k<<1,l,mid,x,y,val);
    if(y>mid) del(k<<1|1,mid+1,r,x,y,val);
    pushup(k,l,r);
}

void move(int k,int l,int r,int x,int y,int val)
{
    if(x<=l && y>=r)
    {
        v[k].move(val);
        v[k].update();
        pushup(k,l,r);
        return ;
    }
    int mid=(l+r)>>1;
    if(x<=mid) move(k<<1,l,mid,x,y,val);
    if(y>mid) move(k<<1|1,mid+1,r,x,y,val);
    pushup(k,l,r);
}

struct rectangle{int d,u,opt,pos;};

vector<rectangle> rec[N];

int main()
{
    n=read();
    register int i,j;
    for(i=1;i<=n;++i)
        L[i]=read(),D[i]=read(),
        R[i]=read(),U[i]=read();
    hsh_map::Main();

    for(i=1;i<=n;++i)
        U[i]--,
        rec[L[i]].push_back((rectangle){D[i],U[i],1,i}),
        rec[R[i]].push_back((rectangle){D[i],U[i],0,i});

    int ans(1);

    for(i=1;i<=n+n;++i)
    {
        for(j=0;j<rec[i].size();++j)
            rec[i][j].opt ? insert(1,1,n+n,rec[i][j].d,rec[i][j].u,rec[i][j].pos) : del(1,1,n+n,rec[i][j].d,rec[i][j].u,rec[i][j].pos);
        while(v[1].mx_remain!=-1)
            ans++,move(1,1,n+n,D[v[1].mx_remain],U[v[1].mx_remain],v[1].mx_remain);
    }

    cout<<ans<<endl;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/blackjack_/article/details/80351087