• LOJ #2729. 「JOISC 2016 Day 1」俄罗斯套娃 扫描线+贪心


    显然,我们可以将每个东西的 $a,b$ 属性转换成二维坐标系中的点.   

    那么我们每次查询的时候查的是一个右下角矩阵.    

    没有被套的数量等于矩阵内总数量减去矩阵内可以套其他物品的数量.       

    我们考虑按照 $a$ 从大到小依次处理.   

    那么对于 $(x,y)$ 来说,显然匹配一个 $(x',y')$ 满足 $y'$ 是大于 $y$ 中最小的是最优的.    

    这个过程用线段树维护就行. 

    code: 

    #include <bits/stdc++.h>       
    #define ll long long     
    #define lson now<<1 
    #define rson now<<1|1   
    #define N 400006 
    #define inf 1000000000   
    #define setIO(s) freopen(s".in","r",stdin)
    using namespace std; 
    int n,Q,B[N];    
    struct data 
    {
        int a,b,opt,id;      
        bool operator<(const data b) const { return a==b.a?opt<b.opt:a>b.a;}  
    }da[N];  
    struct node 
    {
        int minn,sum;   
        node() { minn=inf,sum=0; }   
        node operator+(const node b) const 
        {
            node c;    
            c.sum=sum+b.sum;    
            c.minn=min(minn,b.minn);   
            return c;  
        }
    }s[N<<2];                     
    void update(int l,int r,int now,int p,int v) 
    {   
        s[now].sum+=v;  
        if(l==r) 
        {   
            if(s[now].sum)   
                s[now].minn=l;    
            else 
                s[now].minn=inf;   
            return; 
        }
        int mid=(l+r)>>1;    
        if(p<=mid)   
            update(l,mid,lson,p,v);  
        else 
            update(mid+1,r,rson,p,v);    
        s[now]=s[lson]+s[rson];     
    }    
    node query(int l,int r,int now,int L,int R) 
    {
        if(l>=L&&r<=R)   
            return s[now];  
        int mid=(l+r)>>1;    
        if(L<=mid&&R>mid)  
            return query(l,mid,lson,L,R)+query(mid+1,r,rson,L,R);  
        else if(L<=mid)   
            return query(l,mid,lson,L,R);  
        else 
            return query(mid+1,r,rson,L,R);       
    } 
    int Ans[N];  
    int main() 
    {   
        // setIO("input");     
        int i,j,tot=0;                                   
        scanf("%d%d",&n,&Q);         
        for(i=1;i<=n;++i)    
            scanf("%d%d",&da[i].a,&da[i].b),da[i].opt=0,B[i]=da[i].b;         
        tot=n;   
        for(i=1;i<=Q;++i) 
        {
            ++tot;      
            da[tot].id=i;  
            scanf("%d%d",&da[tot].a,&da[tot].b),da[tot].opt=1,B[tot]=da[tot].b;  
        }                    
        sort(B+1,B+1+tot);   
        for(i=1;i<=tot;++i)  
            da[i].b=lower_bound(B+1,B+1+tot,da[i].b)-B;   
        sort(da+1,da+1+tot);             
        for(i=1;i<=tot;i=j)   
        {        
            for(j=i;da[j].a==da[i].a&&j<=tot;++j);   
            for(int k=i;k<j;++k) 
            {    
                // printf("%d
    ",k);  
                if(da[k].opt==0) 
                {
                    node cu=query(1,tot,1,da[k].b+1,tot);   
                    if(cu.minn!=inf)      
                        update(1,tot,1,cu.minn,-1);      
                }          
            }
            for(int k=i;k<j;++k) 
            {
                if(da[k].opt==0)   
                    update(1,tot,1,da[k].b,1);    
            }
            for(int k=i;k<j;++k)  
            {      
                if(da[k].opt==1)   
                    Ans[da[k].id]=query(1,tot,1,1,da[k].b).sum;    
            }
        }     
        for(i=1;i<=Q;++i)   
            printf("%d
    ",Ans[i]);  
        return 0; 
    }
    

      

  • 相关阅读:
    POJ2762 Going from u to v or from v to u?
    POJ3422或洛谷2045 Kaka's Matrix Travels
    LaTeX数学公式大全
    POJ1966 Cable TV Network
    转:Android中的Handler的机制与用法详解
    Httpservlet cannot be resolved to a type的原因与解决方法
    Textchangedlistener的用法
    contextMenu的使用
    转:android studio 一直卡在Gradle:Build Running的解决办法
    Sqlite操作的一些关键类的官方说明与Intent的startactivityforresult方法
  • 原文地址:https://www.cnblogs.com/guangheli/p/12464069.html
Copyright © 2020-2023  润新知