POJ 2528 Mayor's posters(线段树+离散化)

参照HH牛的模板敲的。RE了3次后发现X数组开小了,坑死爹了。

HH牛的博客:http://www.notonlysuccess.com/index.php/segment-tree-complete/

#include <cstdio>
#include <algorithm>
#include <cstring>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid (l+r)>>1
using namespace std;
const int maxn=10000+5;
bool hash[maxn];
int X[maxn*4];
int col[maxn<<4];
int li[maxn],ri[maxn];
int cnt;
void PushDown(int rt)//更新col到子结点
{
    if(col[rt]!=-1)
    {
        col[rt<<1|1]=col[rt<<1]=col[rt];
        col[rt]=-1;
    }
}
void query(int l,int r,int rt)//查询区间(l,r)之间线段的染色情况
{
    if(col[rt]!=-1)
    {
        if(!hash[col[rt]]) cnt++;
        hash[col[rt]]=true;
        return ;
    }
    if(l==r) return ;
    int m=mid;
    query(lson);
    query(rson);
}
void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        col[rt]=c;
        return ;
    }
    PushDown(rt);
    int m=mid;
    if(m>=L) update(L,R,c,lson);
    if(m<R) update(L,R,c,rson);
}
int Bin(int key,int n,int X[])//二分查找+离散化
{
    int l=0,r=n-1;
    while(l<=r)
    {
        int m=mid;
        if(X[m]==key) return m;
        if(X[m]>key) r=m-1;
        else l=m+1;
    }
    return -1;
}
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        int nn=0;
        for(int i=0;i<n;i++)//所有出现的点存入数组
        {
            scanf("%d%d",&li[i],&ri[i]);
            X[nn++]=li[i];
            X[nn++]=ri[i];
        }
        sort(X,X+nn);
        int m=1;
        for(int i=1;i<nn;i++)//清除重复的点
            if(X[i]!=X[i-1]) X[m++]=X[i];
        for(int i=m-1;i>0;i--)//防止离散化出现问题,详见HH牛的解释
            if(X[i]!=X[i-1]+1) X[m++]=X[i-1]+1;
        sort(X,X+m);
        memset(col,-1,sizeof(col));
        for(int i=0;i<n;i++)
        {
            int l=Bin(li[i],m,X);
            int r=Bin(ri[i],m,X);
            update(l,r,i,0,m,1);
        }
        memset(hash,false,sizeof(hash));
        cnt=0;
        query(0,m,1);
        printf("%d\n",cnt);
    }
    return 0;
}


你可能感兴趣的:(POJ 2528 Mayor's posters(线段树+离散化))