• 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;
    }
  • 相关阅读:
    使用Linux输出重定向将debug信息和ERROR信息分离
    C#中的委托和事件
    C#中如何把函数当做参数传递到别的函数中
    c#中的引用类型和值类型
    浅谈内联函数与宏定义的区别详解
    JVM原理讲解和调优
    判断Python输入是否为数字
    python异常处理
    bmi健康指数
    python查询mangodb
  • 原文地址:https://www.cnblogs.com/-maybe/p/4844234.html
Copyright © 2020-2023  润新知