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

离散化 的大概思路 :   比如说给你一组 数据 1 4 1000 100000,  如果直接
                         开线段, 显然是浪费, 那么我们只要 进行 映射 :
                                1    1  
                                4    2
                             1000    3
                           100000    4
                         接下来 我们只要对 1 2 3 4 建立线段树就行了 只需要
                         [1,4]的区间     
离散化就相当于是先做映射,然后再建树。

本题大意:给定一些海报,可能相互重叠,告诉你每个海报的宽度(高度都一样的)和先后叠放顺序,问没有被完全盖住的有多少张?

海报最多10000张,但是墙有10000000块瓷砖长,海报不会落在瓷砖中间。

如果直接建树,就算不TLE,也会MLE。即单位区间长度太多。

其实10000张海报,有20000个点,最多有19999个区间。对各个区间编号,就是离散化。然后建数。

其实浮点数也是一样离散化的。

刚开始离散化利用map,果断tle了

改了就过了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>

#define ll long long
#define ull unsigned long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

const int maxn=20000+20;

struct Seg
{
    int l,r;
};
Seg seg[maxn>>1];

struct Gao
{
    int v,dir,id,num;
};
Gao gao[maxn];

bool vis[maxn>>1];
int val[maxn<<2];
int lazy[maxn<<2];
int ans;

int solve(int ,int );

int main()
{
    int test;
    scanf("%d",&test);
    while(test--){
        int n;
        scanf("%d",&n);
        int len=0;
        for(int i=1;i<=n;i++){
            int u,v;
            scanf("%d %d",&u,&v);
            seg[i].l=u,seg[i].r=v;
            gao[++len].v=u,gao[len].dir=0,gao[len].id=i;
            gao[++len].v=v,gao[len].dir=1,gao[len].id=i;
        }
        printf("%d
",solve(n,len));
    }
    return 0;
}

bool cmp(Gao x,Gao y)
{
    return x.v<y.v;
}

void pushup(int rt)
{
    if(val[rt<<1]==val[rt<<1|1])
        val[rt]=val[rt<<1];
    else
        val[rt]=-1;
}

void pushdown(int rt)
{
    if(lazy[rt]){
        lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
        val[rt<<1]=val[rt<<1|1]=lazy[rt];
        lazy[rt]=0;
    }
}

void update(int L,int R,int add,int l,int r,int rt)
{
    if(L<=l&&R>=r){
        lazy[rt]=add;
        val[rt]=add;
        return ;
    }
    pushdown(rt);
    int m=(l+r)>>1;
    if(L<=m)
        update(L,R,add,lson);
    if(R>m)
        update(L,R,add,rson);
    pushup(rt);
}

void query(int l,int r,int rt)
{
    if(!val[rt])
        return ;
    if(val[rt]>0){
        if(!vis[val[rt]]){
            ans++;
            vis[val[rt]]=true;
        }
        return ;
    }
    pushdown(rt);
    int m=(l+r)>>1;
    query(lson);
    query(rson);
}

int solve(int n,int len)
{
    sort(gao+1,gao+len+1,cmp);
    int tot=0;
    gao[1].num=++tot;
    for(int i=2;i<=len;i++){
        if(gao[i].v==gao[i-1].v)
            gao[i].num=tot;
        else
            gao[i].num=++tot;
    }

    for(int i=1;i<=len;i++){
        if(!gao[i].dir){
            seg[gao[i].id].l=gao[i].num;
        }
        else{
            seg[gao[i].id].r=gao[i].num;
        }
    }

    memset(val,0,sizeof val);
    memset(lazy,0,sizeof lazy);

    for(int i=1;i<=n;i++){
        update(seg[i].l,seg[i].r,i,1,tot,1);
    }

    memset(vis,false,sizeof vis);
    ans=0;
    query(1,tot,1);

    return ans;
}
原文地址:https://www.cnblogs.com/-maybe/p/4844234.html