• 2020牛客寒假算法基础集训营4 I 匹配星星


    https://ac.nowcoder.com/acm/contest/3005/I

    又做麻烦了,悲催。。。

    将所有星星按x坐标为第一关键字,z为第二关键字排好序

    那么一个z=1的星星匹配的是x比它小的,y比他小但又尽可能大的星星

    用线段树维护所有的y坐标

    如果z=0,直接把y坐标插入线段树

    如果z=1,在线段树中找小于它的y坐标,y又最大的那个星星,线段树中删走

    题解直接用的set,而且在x相同时先处理z=1再处理z=0更方便。唉。。。

    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    
    #define N 100002
    
    struct node
    {
        int x,y;
    }e0[N],e1[N];
    
    int m,has[N]; 
    int sum[N<<2],tot;
    
    bool cmp(node p,node q)
    {
        return p.x<q.x;
    }
    
    void change(int k,int l,int r,int pos,int x)
    {
        sum[k]+=x;
        if(l==r) return;
        int mid=l+r>>1;
        if(pos<=mid) change(k<<1,l,mid,pos,x);
        else change(k<<1|1,mid+1,r,pos,x);
    }
    
    void query2(int k,int l,int r,int opl,int opr)
    {
        if(l>=opl && r<=opr)
        {
            tot+=sum[k];
            return;
        }
        int mid=l+r>>1;
        if(opl<=mid) query2(k<<1,l,mid,opl,opr);
        if(opr>mid) query2(k<<1|1,mid+1,r,opl,opr);
    }
    
    int query(int k,int l,int r,int pos)
    {
        if(l==r) 
            if(sum[k]) return l;
            else return 0;
        int mid=l+r>>1;
        tot=0;
        query2(1,1,m,mid+1,pos);
        if(tot) return query(k<<1|1,mid+1,r,pos);
        return query(k<<1,l,mid,pos);
    }
    
    int main()
    {
        int n,x,y,z,n0=0,n1=0;
        scanf("%d",&n);
        for(int i=1;i<=n;++i) 
        {
            scanf("%d%d%d",&x,&y,&z);
            if(z) e1[++n1].x=x,e1[n1].y=y;
            else e0[++n0].x=x,e0[n0].y=y;
            has[i]=y;
        }
        sort(has+1,has+n+1);
        m=unique(has+1,has+n+1)-has-1;
        sort(e0+1,e0+n0+1,cmp); 
        sort(e1+1,e1+n1+1,cmp);
        e0[n0+1].x=1e9+1;
        int now0=1,now1=1,i,mx,ans=0;
        while(now1<=n1 && e1[now1].x<=e0[1].x) now1++; 
        while(now0<=n0) 
        {
            for(i=now0;i<=n0 && e0[i].x==e0[now0].x;++i) change(1,1,m,lower_bound(has+1,has+m+1,e0[i].y)-has,1);
            while(now1<=n1 && e1[now1].x<=e0[now0+1].x)
            {
                mx=query(1,1,m,lower_bound(has+1,has+m+1,e1[now1].y)-has-1);
                if(mx) change(1,1,m,mx,-1),ans++;
                now1++;
            }
            now0=i;
        }
        printf("%d",ans);
        return 0;
    }    
  • 相关阅读:
    启用Netlogon debug,查看服务器验证瓶颈
    Windows Server 2016调整网卡顺序
    AD用户添加到组
    客户端查看/修改所属站点
    OpenCV相关库
    《塔木德》笔记
    《如何阅读一本书》笔记
    《创业维艰》笔记
    《社会心理学》笔记
    《智能商业》笔记
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12301124.html
Copyright © 2020-2023  润新知