POJ2528 Mayor's posters【线段树+lazy标志+离散化+hash+折半查找】-阿里云开发者社区

开发者社区> 技术小哥哥> 正文

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奶酪博客园博客,原文链接:http://www.cnblogs.com/CheeseZH/archive/2012/05/11/2496536.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Visual Studio查找中文的正则表达式
原文: Visual Studio查找中文的正则表达式 经常有这样的需求:项目代码中有一些输出信息是中文写的,不过现在要做国际化,代码""中写的中文都要改成英文。这样就需要将代码中包含中文的字符串都找出来。
907 0
Codeforces 834D The Bakery【dp+线段树维护+lazy】
D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard input output:standard output ...
957 0
oracle查找索引及表的其它属性
1、查找表的所有索引(包括索引名,类型,构成列):select t.*,i.index_type from user_ind_columns t,user_indexes i where t.index_name = i.
492 0
2010
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载