zoukankan      html  css  js  c++  java
  • bzoj4653 [Noi2016]区间

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4653

    【题解】

    首先把区间按长度从小到大排好序。

    那么取一些区间,花费为长度最大-长度最小,相当于把这个长度区间里面的区间都取了。

    求是不是有一个位置被覆盖超过了m次。

    那么这个用two-pointer和线段树就能实现啦!

    # include <vector>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    int n, m;
    struct intervals {
        int l, r;
        intervals() {}
        intervals(int l, int r) : l(l), r(r) {}
        friend bool operator < (intervals a, intervals b) {
            return a.r-a.l < b.r-b.l;
        }
    }p[M], a[M];
    
    vector<int> ps;
    
    namespace SGT {
        const int M = 4e6 + 10;
        int w[M], lazy[M];
        # define ls (x<<1)
        # define rs (x<<1|1)
        inline void down(int x) {
            if(!x) return ;
            if(!lazy[x]) return ;
            w[ls] += lazy[x], lazy[ls] += lazy[x];
            w[rs] += lazy[x], lazy[rs] += lazy[x];
            lazy[x] = 0;
        }
        inline void change(int x, int l, int r, int L, int R, int d) {
            if(L <= l && r <= R) {
                w[x] += d;
                lazy[x] += d;
                return ;
            }
            down(x);
            int mid = l+r>>1;
            if(L <= mid) change(ls, l, mid, L, R, d);
            if(R > mid) change(rs, mid+1, r, L, R, d);
            w[x] = max(w[ls], w[rs]);
        }
        inline int get() {
            return w[1];
        }
    }
    
    int main() {
        cin >> n >> m;
        for (int i=1; i<=n; ++i) scanf("%d%d", &p[i].l, &p[i].r);
        sort(p+1, p+n+1);
        for (int i=1; i<=n; ++i) ps.push_back(p[i].l), ps.push_back(p[i].r);
        sort(ps.begin(), ps.end());
        ps.erase(unique(ps.begin(), ps.end()), ps.end());
        for (int i=1; i<=n; ++i) {
            a[i].l = lower_bound(ps.begin(), ps.end(), p[i].l) - ps.begin() + 1;
            a[i].r = lower_bound(ps.begin(), ps.end(), p[i].r) - ps.begin() + 1;
        }
        int mx = ps.size(), ans = 1e9;
        for (int l=1, r=0; l<=n; ++l) {
            if(SGT::get() != m) {
                while(r<n) {
                    ++r;
                    SGT::change(1, 1, mx, a[r].l, a[r].r, 1);
                    if(SGT::get() == m) break;
                }
            }
            if(SGT::get() != m) break;
            ans = min(ans, p[r].r - p[r].l - p[l].r + p[l].l);
            SGT::change(1, 1, mx, a[l].l, a[l].r, -1);
        }
        if(ans == 1e9) cout << -1;
        else cout << ans;
        return 0;
    }
    View Code
  • 相关阅读:
    Vuforia7+Unity2017.3.f3实践练习
    pureMVC+unity
    sql语法小结
    ScreenToViewportPoint,WorldToViewportPoint,ViewportToWorldPoint的运用,实现一个简单的对三维中物体的拖拽移动效果
    Unity游戏开发学习之路——数据持久化
    Unity游戏开发之路上的那些坑——NullReferenceException
    ffmpeg-音频视频处理
    微信开发之(五)接收语音识别结果
    微信开发之(五)获取media_id的值
    微信开发之(五)微信获取自定义菜单
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj4653.html
Copyright © 2011-2022 走看看