zoukankan      html  css  js  c++  java
  • hihoCoder:#1079(线段树+离散化)

    题目大意:给n个区间,有的区间可能覆盖掉其他区间,问没有完全被其他区间覆盖的区间有几个?区间依次给出,如果有两个区间完全一样,则视为后面的覆盖前面的。

    题目分析:区间可能很长,所以要将其离散化。但离散化之后区间就变成了连续的,不再是离散的。也就是叶子由左右端点为u、u变成了左右端点为u-1、u,左右儿子有(l,mid)和(mid+1,r)变成了(l,mid)和(mid,r)。所以离散化之后要以长度为1的区间为叶子节点建立线段树,而不是以1、2、3...为叶子节点建线段树。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<set>
    # include<map>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int N=200000;
    
    int tr[N*4+5];
    int n,m;
    int lazy[N*4+5];
    int x[N+5],y[N+5];
    set<int>s;
    map<int,int>mp;
    int num[N+5];
    
    void pushDown(int rt,int l,int r)
    {
        if(lazy[rt]==-1) return ;
        lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
        tr[rt<<1]=tr[rt<<1|1]=tr[rt];
        lazy[rt]=-1;
    }
    
    void update(int rt,int l,int r,int L,int R,int val)
    {
        if(L<=l&&r<=R){
            tr[rt]=val;
            lazy[rt]=val;
        }else{
            pushDown(rt,l,r);
            int mid=l+(r-l)/2;
            if(L<=mid) update(rt<<1,l,mid,L,R,val);
            if(R>mid) update(rt<<1|1,mid+1,r,L,R,val);
        }
    }
    
    void query(int rt,int l,int r)
    {
        if(l==r){
            if(tr[rt]!=-1) s.insert(tr[rt]);
            return ;
        }
        if(lazy[rt]!=-1){
            s.insert(tr[rt]);
            return ;
        }
        int mid=l+(r-l)/2;
        query(rt<<1,l,mid);
        query(rt<<1|1,mid+1,r);
    }
    
    int f(int l,int r,int x)
    {
        while(l<r){
            int mid=l+(r-l)/2;
            if(num[mid]<x)
                l=mid+1;
            else
                r=mid;
        }
        return l;
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            num[0]=0;
            mp.clear();
            for(int i=0;i<n;++i){
                scanf("%d%d",x+i,y+i);
                if(mp[x[i]]==0) num[++num[0]]=x[i],++mp[x[i]];
                if(mp[y[i]]==0) num[++num[0]]=y[i],++mp[y[i]];
            }
            sort(num+1,num+num[0]+1);
            memset(tr,-1,sizeof(tr));
            memset(lazy,-1,sizeof(lazy));
            for(int i=0;i<n;++i){
                int a=f(1,num[0]+1,x[i]);
                int b=f(1,num[0]+1,y[i]);
                update(1,1,num[0]-1,a,b-1,i);
            }
            s.clear();
            query(1,1,num[0]-1);
            printf("%d
    ",s.size());
        }
        return 0;
    }
    

      

  • 相关阅读:
    Spring的AOP与代理
    JAVA 反射机制
    JDK动态代理与Cglib库
    HDFS的运行原理(转)
    Spring中IoC的入门实例
    spring
    Spring中IOC和AOP的详细解释
    自己动手写ORM
    Mongodb 安装
    mongodb集群配置分片集群
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5474672.html
Copyright © 2011-2022 走看看