POJ 2528

离散化,然后线段树
离散化技巧可以见代码,具体参考《挑战程序设计》的坐标离散化,类似

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=8e5+5;
const int maxm=2e5+5;
struct note{
    int l,r;
    int color;
}a[maxn];
bool used[maxn];
int n,c,m;
void init_(int i,int l,int r){
    a[i].l=l;
    a[i].r=r;
    a[i].color=0;
    if(l==r)return ;
    int mid=(l+r)>>1;
    init_(i<<1,l,mid);
    init_(i<<1 |1,mid+1,r);
}
void updata(int i,int l,int r,int c){
    if(a[i].l==l&&a[i].r==r){
       a[i].color=c;
       return;
    }
    if(a[i].color){
        a[i<<1].color=a[i<<1 |1].color=a[i].color;
        a[i].color=0;
    }
    int mid=(a[i].l+a[i].r)>>1;
     if(l>mid) updata(i<<1 |1,l,r,c);
     else if(r<=mid) updata(i<<1,l,r,c);
     else {updata(i<<1,l,mid,c);updata(i<<1 |1,mid+1,r,c);}
}
int ans;
void solve1(int i,int l,int r){
    if(a[i].color){
       if(!used[a[i].color])
        ans++,used[a[i].color]=true;
       return;
    }
    if(l==r)return;
    if(a[i].color){
        a[i<<1].color=a[i<<1 |1].color=a[i].color;
        a[i].color=0;
    }
    int mid=(a[i].l+a[i].r)>>1;
     if(l>mid) solve1(i<<1 |1,l,r);
     else if(r<=mid) solve1(i<<1,l,r);
     else {solve1(i<<1,l,mid);solve1(i<<1 |1,mid+1,r);}
}

inline void scanf_(int &data){
    char ch = getchar();
    while (ch < '0' || ch > '9')
        ch = getchar();
    data = 0;
    do{
        data = data*10 + ch-'0';
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9');
}
int x[maxm],y[maxm];
int sum[maxn];
int solve_(int X1[],int X2[]){
    vector<int>vec;
    vec.clear();
    for(int i=1;i<=n;i++){
        for(int d=-1;d<=1;d++){
            int tx=d+X1[i],ty=d+X2[i];
                vec.push_back(tx);vec.push_back(ty);
        }
    }
    sort(vec.begin(),vec.end());
    vec.erase(unique(vec.begin(),vec.end()),vec.end());
    for(int i=1;i<=n;i++){
        X1[i]=lower_bound(vec.begin(),vec.end(),X1[i])-vec.begin()+1;
        X2[i]=lower_bound(vec.begin(),vec.end(),X2[i])-vec.begin()+1;
    }

    return vec.size();
}
int xx[maxn];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%",&n);
        if(!n){
            puts("0");continue;
        }
        for(int i=1;i<=n;i++){
            scanf_(x[i]);
            scanf_(y[i]);
        }
        int coun=solve_(x,y);
        init_(1,1,coun);
        ans=0;
        for(int i=1;i<=n;i++){
            updata(1,x[i],y[i],i);
        }
        memset(used,false,sizeof(used));
        solve1(1,1,coun);
        printf("%d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(POJ 2528)