• [POI 2018] Prawnicy


    [题目链接]

                https://www.lydsy.com/JudgeOnline/problem.php?id=5102

    [算法]

             首先,n条线段的交集一定是[Lmax,Rmin] , 其中,Lmax为最靠右的左端点,Rmin为最靠左的右端点

             根据这个性质 , 我们不妨将所有线段按左端点为关键字排序 , 依次枚举最终交集的左端点 , 同时 , 我们还需维护一个小根堆 , 维护前k大的右端点 , 每次我们通过( 堆顶 - 当前枚举线段的左端点 )更新答案

    [代码]

           

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 1000010
    
    struct segment
    {
            int id;
            int l,r;
    } a[MAXN];
    
    int n,k,ans,l,r,len;
    priority_queue< pair<int,int> > q;
    int res[MAXN];
    
    template <typename T> inline void read(T &x)
    {
        int f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; 
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline bool cmp(segment a,segment b)
    {
            if (a.l == b.l) return a.r > b.r;
            else return a.l < b.l;
    }
    
    int main() 
    {
            
            read(n); read(k);
            for (int i = 1; i <= n; i++) 
            {
                    a[i].id = i;
                    read(a[i].l);
                    read(a[i].r);        
            }
            sort(a + 1,a + n + 1,cmp);
            ans = 0;
            for (int i = 1; i <= n; i++)
            {
                    if ((int)q.size() < k) 
                    {
                            q.push(make_pair(-a[i].r,a[i].id));
                            if ((int)q.size() == k) 
                            {
                                    ans = max(ans,-q.top().first - a[i].l);
                                    l = a[i].l; r = -q.top().first;
                                    continue;
                            }
                    } else
                    {
                            if (a[i].r < -q.top().first) continue;
                            pair<int,int> tmp = q.top();
                            q.pop();
                            q.push(make_pair(-a[i].r,a[i].id));
                            if (-q.top().first - a[i].l > ans)
                            {
                                    ans = -q.top().first - a[i].l;
                                    l = a[i].l; r = -q.top().first;
                            }
                    }    
            }
            printf("%d
    ",ans);
            if (ans == 0)
            {
                    for (int i = 1; i <= k; i++)
                            printf("%d ",i);
                    printf("
    ");
                    return 0;
            }
            for (int i = 1; i <= n; i++)
            {
                    if (a[i].l <= l && a[i].r >= r)
                    {
                            res[++len] = a[i].id;
                            if ((--k) == 0) break;
                    }
            }
            for (int i = 1; i <= len; i++) printf("%d ",res[i]);
            printf("
    ");
            
            return 0;
        
    }
  • 相关阅读:
    c# yield关键字原理详解
    Linux环境基于CentOS7 搭建部署Docker容器
    关于c#中委托使用小结
    推荐一本好的c#高级程序设计教程
    WEB网站常见受攻击方式及解决办法
    判断URL是否存在
    提升高并发量服务器性能解决思路
    分享asp.net学习交流社区
    js中对arry数组的各种操作小结
    jQuery动态实现title的修改 失效问题
  • 原文地址:https://www.cnblogs.com/evenbao/p/9538926.html
Copyright © 2020-2023  润新知