zoukankan      html  css  js  c++  java
  • [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;
        
    }
  • 相关阅读:
    [NOIP2017]宝藏 子集DP
    [NOI2017]蔬菜 贪心
    hihoCoder#1698 : 假期计划 组合数
    KNIGHTS
    动态图连通性(线段树分治+按秩合并并查集)
    CF868F Yet Another Minimization Problem 分治决策单调性优化DP
    【POJ】【3308】Paratroopers
    【BZOJ】【3437】小P的牧场
    【BZOJ】【3156】防御准备
    【BZOJ】【1010】【HNOI2008】玩具装箱Toy
  • 原文地址:https://www.cnblogs.com/evenbao/p/9538926.html
Copyright © 2011-2022 走看看