zoukankan      html  css  js  c++  java
  • POJ2528 线段树的区间操作

    首先应该对该【0,10000000】进行离散化

    即先将点集进行排序,然后从小到大缩小其中的间距,使得最后点数不会超过2*n

    然后就是线段树操作

    只需进行染色,然后最后用nlgn进行一个个查询颜色记录即可


    #include<cstdio>

    #include<cstring>
    int color[20005*4],a[20005],p[20005],l[10005],r[10005],pd[10005],i,j,k,n,t,length;
    void qs(int x,int y){
        int i=x,j=y,k=a[(x+y)/2],t;
        do{
            while(a[i]<k) i++;
            while(a[j]>k) j--;
            if(i<=j){
                t=a[i];a[i]=a[j];a[j]=t;
                t=p[i];p[i]=p[j];p[j]=t;
                i++;j--;
            }
        }while(i<j);
        if(i<y) qs(i,y);
        if(x<j) qs(x,j);
    }
    void build(int x,int y,int rt){
        color[rt]=0;
        if(x>=y) return;
        int m=(x+y)/2;
        build(x,m,2*rt);
        build(m+1,y,2*rt+1);
    }
    void PushDown(int rt){
        if(color[rt]!=0){
            color[rt*2]=color[rt*2+1]=color[rt];
            color[rt]=0;
        }
    }
    void update(int x,int y,int rt){
        if(l[k]<=x&&r[k]>=y){
            color[rt]=k;
            return;
        }
        PushDown(rt);
        int m=(x+y)/2;
        if(l[k]<=m) update(x,m,rt*2);
        if(r[k]>m) update(m+1,y,rt*2+1);
    }
    int query(int x,int y,int rt){
        if(color[rt]!=0){
            if(!pd[color[rt]]) {
                pd[color[rt]]=1;
                return 1;
            }
            else return 0;
        }
        if(x==y) return 0;
        int m=(x+y)/2;
        return(query(x,m,rt*2)+query(m+1,y,rt*2+1));
    }
    int main()
    {
        scanf("%d",&t);
        while(t--){
            memset(pd,0,sizeof(pd));
            scanf("%d",&n);
            for(i=1;i<=n;i++){
                scanf("%d%d",&a[2*i-1],&a[2*i]);
                p[2*i-1]=2*i-1;
                p[2*i]=2*i;
            }
            qs(1,2*n);
            length=1;
            for(i=1;i<=2*n;i++){
                if(p[i]%2==0)
                    r[p[i]/2]=length;
                else
                    l[(p[i]+1)/2]=length;
                if(a[i]!=a[i+1]) length++;
            }
            build(1,length,1);
            for(k=1;k<=n;k++)
                update(1,length,1);
            printf("%d ",query(1,length,1));
        }
        return 0;
    }

  • 相关阅读:
    VisualSVN 服务不能自动启动的问题
    "There is already an open DataReader associated with this Command which must be closed first"错误
    LINQ 中调用存储过程自动绑定列名
    vs2008中调试iis7.0托管的程序
    SQL SERVER 2005的一个怪问题: 在查询结果面板中编辑失败.
    在VS2003下把一个DataTable Update 到数据库
    帮人解决一个小问题:QQ空间登录时脚本错误造成无法登入
    关于Sys未定义错误
    多层母版页嵌套中, 内层母版页的事件默认不触发
    线程同步
  • 原文地址:https://www.cnblogs.com/Mathics/p/3681176.html
Copyright © 2011-2022 走看看