zoukankan      html  css  js  c++  java
  • [NOI 2016] 区间

    [题目链接]

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

    [算法]

            首先将区间按长度排序

            那么 , 满足条件的一定是一段连续的区间 , [Li , Ri] , [Li+1,Ri+1] ... [Lj , Rj]

            我们不妨枚举每一个L ,  不难发现当L递增时 , 满足条件的 , 最小的R同样是单调递增的 , 不妨用Two-Pointers计算这个最小的R并更新答案

            我们还需用线段树维护当前被覆盖最多次的位置被覆盖了多少次

            由于每个位置都会被访问并更新一次 , 故时间复杂度为 : O(NlogN)

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 500010
    #define MAXM 200010
    const int inf = 2e9;
    
    struct range
    {
            int l , r;
    } a[MAXN];
    
    int n , m , len;
    int tmp[MAXN << 1] , l[MAXN] , r[MAXN];
    
    struct Segment_Tree
    {
            struct Node
            {
                    int l , r;
                    int mx , tag;
            } Tree[MAXN << 4];
            inline void build(int index , int l , int r)
            {    
                    Tree[index].l = l;
                    Tree[index].r = r;
                    Tree[index].mx = Tree[index].tag = 0;
                    if (l == r) return;
                    int mid = (l + r) >> 1;
                    build(index << 1 , l , mid);
                    build(index << 1 | 1 , mid + 1 , r);
            }
            inline void pushdown(int index)
            {
                    Tree[index << 1].mx += Tree[index].tag;
                    Tree[index << 1 | 1].mx += Tree[index].tag;
                    Tree[index << 1].tag += Tree[index].tag;
                    Tree[index << 1 | 1].tag += Tree[index].tag;
                    Tree[index].tag = 0;
            }
            inline void update(int index)
            {
                    Tree[index].mx = max(Tree[index << 1].mx , Tree[index << 1 | 1].mx);
            }
            inline void modify(int index , int l ,int r , int value)
            {
                    if (Tree[index].l == l && Tree[index].r == r)
                    {
                            Tree[index].mx += value;
                            Tree[index].tag += value;
                            return;
                    }
                    pushdown(index);
                    int mid = (Tree[index].l + Tree[index].r) >> 1;
                    if (mid >= r) modify(index << 1 , l , r , value);
                    else if (mid + 1 <= l) modify(index << 1 | 1 , l , r , value);
                    else
                    {
                            modify(index << 1 , l , mid , value);
                            modify(index << 1 | 1 , mid + 1 , r , value);
                    }
                    update(index);
            }
            inline int query()
            {
                    return Tree[1].mx;
            }
    } SGT;
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T 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(range a , range b)
    {
            return a.r - a.l < b.r - b.l;
    }
    
    int main()
    {
            
            read(n); read(m);
            for (int i = 1; i <= n; i++)
            {
                    read(a[i].l);
                    read(a[i].r);
                    tmp[i * 2 - 1] = a[i].l;
                    tmp[i * 2] = a[i].r;        
            }
            sort(tmp + 1 , tmp + 2 * n + 1);
            len = unique(tmp + 1 , tmp + 2 * n + 1) - tmp - 1;
            sort(a + 1 , a + n + 1 , cmp);
            for (int i = 1; i <= n; i++)
            {
                    l[i] = lower_bound(tmp + 1 , tmp + len + 1 , a[i].l) - tmp;
                    r[i] = lower_bound(tmp + 1 , tmp + len + 1 , a[i].r) - tmp;        
            }
            SGT.build(1 , 1 , len);
            int ans = inf , rgt = 0;
            for (int i = 1; i <= n; i++)
            {
                    bool flg = false;
                    while (rgt <= n)
                    {
                            if (SGT.query() >= m) 
                            {    
                                    flg = true;
                                    break;
                            }
                            ++rgt;
                            if (rgt > n) break;
                            SGT.modify(1 , l[rgt] , r[rgt] , 1);
                    }
                    if (flg) chkmin(ans , (tmp[r[rgt]] - tmp[l[rgt]]) - (tmp[r[i]] - tmp[l[i]]));
                    else break;
                    SGT.modify(1 , l[i] , r[i] , -1);
            }
            printf("%d
    " , ans != inf ? ans : -1);
            
            return 0;
        
    }
  • 相关阅读:
    神经网络系列学习笔记(一)——神经网络之ANN学习资料汇总
    时间序列分析算法学习笔记
    推荐算法学习笔记
    神经网络系列学习笔记(二)——神经网络之DNN学习笔记
    AB test学习笔记
    大数据的存储——HBase、HIVE、MYSQL数据库学习笔记
    本地已经存在的项目如何跟github发生关联
    深度神经网络对脑电信号运动想象动作的在线解码
    脑机音乐接口,高效检测用户的情绪状态
    将深度学习技术应用于基于情境感知的情绪识别
  • 原文地址:https://www.cnblogs.com/evenbao/p/9866969.html
Copyright © 2011-2022 走看看