BZOJ 5102: [POI2018]Prawnicy 贪心+堆

貌似是套路题. 

假设给定我们一些区间,那么这些区间交集的左端点是左端点最靠右区间的左端点. 

所以我们将所有区间按照左端点从小到大排序,然后用堆维护前 k 大的右端点.  

那么,对于枚举到的第 $i$ 个区间来说,右端点就是第 $k$ 大的右端点与当前区间右端点的较小值. 

code: 

#include <cstdio> 
#include <string>  
#include <cstring>  
#include <queue>  
#include <cctype>
#include <algorithm>     

#define N 1000050 

using namespace std;   

namespace IO {  

    void setIO(string s) 
    {
        string in=s+".in"; 
        string out=s+".out"; 
        freopen(in.c_str(),"r",stdin); 
    } 
    inline char nc()
    {
        static char buf[100000] , *p1 , *p2;
        return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 100000 , stdin) , p1 == p2) ? EOF : *p1 ++ ;
    }
    inline int rd()
    {
        int ret = 0; char ch = nc();
        while(!isdigit(ch)) ch = nc();
        while(isdigit(ch)) ret = ((ret + (ret << 2)) << 1) + (ch ^ '0') , ch = nc();
        return ret;
    }
}; 

int n,k,ans,A[N];  
struct node {
    int l,r,id;     
    node(int l=0,int r=0,int id=0):l(l),r(r),id(id){}   
    bool operator<(node b) const { return r>b.r; }   
}arr[N];    
priority_queue<node>q;        
bool cmp(node a,node b) { return a.l<b.l; }     

int main() 
{    
    // IO::setIO("input"); 
    int i,j,mx=0; 
    using namespace IO;  
    n=rd(),k=rd(); 
    for(i=1;i<=n;++i) 
    {
        arr[i].l=rd(),arr[i].r=rd(); 
        arr[i].id=i;     
    }     
    sort(arr+1,arr+1+n,cmp);            
    for(i=1;i<=n;++i) 
    {
        q.push(arr[i]); 
        if(i<k) continue;  
        else
        {         
            if(i>k) q.pop();  
            node p=q.top();      
            mx=max(mx,min(arr[i].r,q.top().r)-arr[i].l);    
        }
    }          
    printf("%d\n",mx);        
    while(!q.empty()) q.pop();   
    for(i=1;i<=n;++i) 
    {
        if(i<k) q.push(arr[i]);  
        else
        {
            node p=q.top();    
            q.push(arr[i]); 
            if(i>k) q.pop();  
            int now=q.top().r-arr[i].l;       
            if(now==mx) 
            {     
                int tot=0; 
                while(!q.empty()) A[++tot]=q.top().id,q.pop();  
                sort(A+1,A+1+tot); 
                for(i=1;i<=tot;++i) printf("%d ",A[i]); 
                return 0; 
            }     
        }
    }
    return 0; 
}

  

posted @ 2019-12-28 16:51  EM-LGH  阅读(114)  评论(0编辑  收藏  举报