• POJ2528 Mayor's posters【线段树+lazy标志+离散化+hash+折半查找】


    Problem: 2528   User: qq1203456195
    Memory: 1120K   Time: 94MS
    Language: C++   Result: Accepted
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define maxn 11111
    int hash[maxn];
    int li[maxn],ri[maxn];
    int X[maxn<<4];
    int col[maxn<<4];//maxn张海报对应maxn<<1个边界,最多需要添加maxn<<1个辅助点,即的线段树要((maxn<<1)<<1)<<2个结点。
    int cnt;
    
    void PushDown(int rt)//lazy标志位下传
    {
        if(col[rt]!=-1)
        {
            col[rt<<1]=col[rt<<1|1]=col[rt];
            col[rt]=-1;
        }
    }
    
    void update(int L,int R,int C,int l,int r,int rt)
    {
        int m=(l+r)>>1;
        if(L<=l&&r<=R)
        {
            col[rt]=C;
            return;
        }
        PushDown(rt);
        if (L<=m)    update(L,R,C,lson);
        if (m< R)    update(L,R,C,rson);
    
    }
    void query(int l,int r,int rt)
    {
        int m=(l+r)>>1;
        if(col[rt]!=-1)
        {
            if(!hash[col[rt]])
                cnt++;
            hash[col[rt]]=1;
            return;
        }
        if(l==r)    return;
        query(lson);
        query(rson);
    
    }
    int Bin(int key,int len,int *x)//在长度为len的数组中二分查找key的位置
    {
        int l=0,r=len;
        int m;
        while(l<=r)
        {
            m=(l+r)>>1;
            if(x[m]==key)    return m;
            if(x[m]<key)    l=m+1;
            else            r=m-1;
        }
        return -1;
    }
    int main()
    {
        int i,m,n,p,cas,L,R,C;
        scanf("%d",&cas);
        while (cas--)
        {
            scanf("%d",&n);
            //读取数据,并构造待离散化数组X,离散化第一步
            p=0;
            for (i=0;i<n;i++)
            {
                scanf("%d%d",&li[i],&ri[i]);
                X[p++]=li[i];
                X[p++]=ri[i];
            }
            //将X内数据排序,离散化第二步(注意数据范围:x[0]...x[p-1])
            sort(X,X+p);
            //去掉X内重复值,离散化第三步
            /*从1开始,到p-1为止*/
            m=1;
            for (i=1;i<p;i++)
            {
                if(X[i]!=X[i-1])//如果不等,说明没有出现过,就保留;否则就丢弃。
                    X[m++]=X[i];
            }
            /*难点!如果出现1,2,5,9这种数据,就改成1,2,5,6,9
            也就是说如果相邻数字间距大于1的话,在其中加上任意一个和相邻数字中的某个数字
            差值为1的数字
            */
            for (i=m-1;i>0;i--)
            {
                if(X[i]!=X[i-1]+1)
                    X[m++]=X[i-1]+1;
            }
            sort(X,X+m);//(注意数据范围:x[0]...x[m-1])
            //离散化结束,只需建立叶子节点为m的线段树即可,X[m]的值就是输入的数据中的一个。
            //为了统计海报的个数,就需要海报的标记,而li,ri的下标就可以做海报的标记
            //创建线段树
            memset(col,-1,sizeof(col));
            for (i=0;i<n;i++)
            {
                L=Bin(li[i],m-1,X);
                R=Bin(ri[i],m-1,X);
                C=i;
                update(L,R,C,0,m,1);
            }
            //统计海报个数
            cnt=0;
            memset(hash,0,sizeof(hash));
            query(0,m,1);
            printf("%d\n",cnt);
        }
        return 0;
    }
    字节跳动内推

    找我内推: 字节跳动各种岗位
    作者: ZH奶酪(张贺)
    邮箱: cheesezh@qq.com
    出处: http://www.cnblogs.com/CheeseZH/
    * 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    (Ubuntu)下载及安装Genymosion模拟器并配置Android Studio
    ROS CMakeLists中target_link_libraries相对路径设置
    VS_C#快捷键
    一行代码实现各产品访问统计???[原创]
    PyCharm下载安装
    装饰模式(Decorator)
    Python之格式化输出
    python入门
    servlet--http接口简单的创建及调用
    Storm-jdbc-2讲 高级API及Trident
  • 原文地址:https://www.cnblogs.com/CheeseZH/p/2496536.html
Copyright © 2020-2023  润新知