zoukankan      html  css  js  c++  java
  • 【POJ2528】Mayor's posters

    题意

    给出n个区间,n<=10000, 依次将每个区间涂上不同 的颜色,问最后还能看见多少种颜色

    输入 

    第一行是一个整数t表示t组数据  对于每组数据:  第1行是n表示有n个区间  接下来n行2个整数L,R表示区间(1<=L<=R<=10000000)

    分析

    从区间的问题很明显的看出是线段树,做法也很简单,将没有颜色的点标为-1,有多种颜色的区间标为0,有一种颜色的用1~n代表颜色,最后查询出整个区间的颜色数量就行了

    但是问题在于区间的范围很大,数组无法承受

    所以是一个基础的离散化

    离散化的方法简单来说就是通过排序,保持序列l和r的有序性,将排序后的顺序作为新的序号,这样有效地降低了数值大小。

    需要注意的是,如果说两端点中间还有其他数,那必须再生成一个节点。

    比如 这三对数:1 10  1 3  5 10 答案应该是3,但是离散后答案会变成2,这就是因为中间没生成一个点来代表两数之间的数的原因。

    通过unique去重,lower_bound查找要用的节点离散后的位置即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 2020000
    #define lc (p<<1)
    #define rc (p<<1|1)
    #define mid (t[p].l+t[p].r>>1)
    int T,n,m,tot,ans;
    int col[N],num[N],a[N],ls[N],rs[N];
    struct email
    {
        int l,r,lazy,c;
    }t[N*4];
    
    inline void pushnow(int p,int c)
    {
        t[p].lazy=c;
        t[p].c=c;
    }
    
    inline void pushup(int p)
    {
        if(!t[lc].c||!t[rc].c||t[lc].c!=t[rc].c)
            t[p].c=0;
        else
            t[p].c=t[rc].c;
    }
    
    inline void pushdown(int p)
    {
        if(t[p].lazy!=-1)
        {
            pushnow(lc,t[p].lazy);
            pushnow(rc,t[p].lazy);
            t[p].lazy=-1;
        }
    }
    
    void build(int p,int l,int r)
    {
        t[p].l=l,t[p].r=r;
        if(l==r)
        {
            t[p].c=-1;
            t[p].lazy=-1;
            return ;
        }
        build(lc,l,mid);build(rc,mid+1,r);
        pushup(p);
    }
    
    void update(int p,int ql,int qr,int c)
    {
        if(ql<=t[p].l&&t[p].r<=qr)
        {
            pushnow(p,c);
            return;
        }
        pushdown(p);
        if(ql<=mid)update(lc,ql,qr,c);
        if(qr>mid)update(rc,ql,qr,c);
        pushup(p);
    }
    
    void query(int p,int ql,int qr)
    {
        if(t[p].c==-1)
            return ;
        else
            if(t[p].c>0)
            {
                col[t[p].c]=1;
                return ;
            }
        pushdown(p);
        if(ql<=mid)    query(lc,ql,qr);
        if(qr>mid)     query(rc,ql,qr);
        
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            ans=0;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                int pl,pr;
                scanf("%d%d",&pl,&pr);
                ls[i]=pl;rs[i]=pr;
                num[i*2-1]=pl;num[i*2]=pr;
            }
            sort(num+1,num+1+2*n);
            m=unique(num+1,num+1+2*n)-(num+1);
            tot=m;
            for(int i=1;i<m;i++)
                if(num[i]+1<num[i+1])
                    num[++tot]=num[i]+1;
            sort(num+1,num+1+tot);
            build(1,1,tot);
            memset(col,0,sizeof(col));
            for(int i=1;i<=n;i++)
            {
                int x=lower_bound(num+1,num+1+tot,ls[i])-num;
                int y=lower_bound(num+1,num+1+tot,rs[i])-num;
                update(1,x,y,i);
            }
            query(1,1,tot);
            for(int i=1;i<=n;i++)
                if(col[i])
                    ans++;
            printf("%d
    ",ans);
        }
        return 0;
    }
    “Make my parents proud,and impress the girl I like.”
  • 相关阅读:
    maplestory【Lotus prequest】---2.3、bestow
    springboot拦截器过滤token,并返回结果及异常处理
    'axios' is not defined
    MSBUILD : error MSB3428: 未能加载 Visual C++ 组件“VCBuild.exe”。
    VS Code(Visual Studio Code)
    学习CSS+HTML+JS到底用什么编辑器或IDE
    SpringBoot整合Mybatis完整详细版 入门资料
    Oracle 导出视图view中的数据
    oracle 时间 比较
    分子对接
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9452069.html
Copyright © 2011-2022 走看看