POJ 2528 Mayor's posters 简单的线段树 + 离散化

在一个被分成 10000000 段的墙上贴海报,从第Li段 贴到 第Ri段。

      问最后能看见几张海报。

      如果直接建立线段树注定要各种 LE。但是只会有1W张海报,所以对其离散化,这样只有2W+个点。

      还有一种特殊情况就是原本不会被完全覆盖掉的海报会因离散化而被完全覆盖。

      如:

3

 1  10

    1  6

7  10

3

1  10

1  6

9  10

 所以要字啊离散化的的时候注意一下,如果相邻两点相差 > 1 ,则应在此多加一个点,来标记之间还有一段。


#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;

struct N
{
    int l,r;
}arr[10010];

struct T
{
    int l,r,col;
    bool ms;
}st[161100];

int num[20010];
int sta[40010];

int top;

int binarysearch(int key)
{
    int s = 1;
    int e = top;
    int mid;
    while(s <= e)
    {
        mid = (s+e)>>1;
        if(key == sta[mid])
            return mid;
        if(key < sta[mid])
            e = mid-1;
        else s = mid+1;
    }
}

void updata(int l,int r,int color,int site)
{
    if(l == st[site].l && r == st[site].r)
    {
        st[site].ms = true;
        st[site].col = color;
        return ;
    }

    int mid = (st[site].l + st[site].r)>>1;

    if(st[site].ms == true && st[site].col != 0)
    {
        updata(st[site].l,mid,st[site].col,site<<1);
        updata(mid+1,st[site].r,st[site].col,site<<1|1);
    }

    st[site].ms = false;

    if(r <= mid)
    {
        updata(l,r,color,site<<1);
    }
    else if(mid < l)
    {
        updata(l,r,color,site<<1|1);
    }
    else
    {
        updata(l,mid,color,site<<1);
        updata(mid+1,r,color,site<<1|1);
    }
}

bool MarkVisit[10010];

int query(int site)
{
    if(st[site].ms == true)
    {
        if(MarkVisit[st[site].col] == false)
        {
            MarkVisit[st[site].col] = true;
            return 1;
        }
        return 0;
    }
    return query(site<<1) + query(site<<1|1);
}

void init(int L,int R,int site)
{
    st[site].l = L;
    st[site].r = R;
    st[site].col = 0;//col == 0 表示墙原本的颜色
    st[site].ms = true;//表示单色

    if(L == R)
        return ;

    int mid = (L+R)>>1;

    init(L,mid,site<<1);
    init(mid+1,R,site<<1|1);
}

int main()
{
    int i,j,n,l,r,T;
    scanf("%d",&T);
    while(T--)
    {
        top = 0;
        scanf("%d",&n);
        for(i = 1;i <= n; ++i)
        {
            scanf("%d %d",&arr[i].l,&arr[i].r);
            num[top++] = arr[i].l;
            num[top++] = arr[i].r;
        }

        sort(num,num+top);

        sta[1] = num[0];

        for(i = 1,j = 2;i < top; ++i)
        {
            if(num[i] != sta[j-1])
            {
                if(num[i] - sta[j-1] != 1)
                {
                    sta[j++] = num[i]-1;
                }
                sta[j++] = num[i];
            }
        }

        top = j-1;

        init(1,top,1);

        for(i = 1;i <= n; ++i)
        {
            int tl = binarysearch(arr[i].l);
            int tr = binarysearch(arr[i].r);
            updata(tl,tr,i,1);
        }
        memset(MarkVisit,false,(n+2)*sizeof(bool));
        MarkVisit[0] = true;
        printf("%d\n",query(1));
    }
    return 0;
}

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