zoukankan      html  css  js  c++  java
  • [NOI2016 D2T1]区间

    题目大意:在数轴上有$n$个闭区间$[l_1,r_1],[l_2,r_2],...,[l_n,r_n]$。现在要从中选出 $m$ 个区间,使得这 $m$ 个区间共同包含至少一个位置。输出被选中的最长区间长度减去被选中的最短区间长度,若多解,输出最小的一个

    题解:把区间按长度排序,然后把左右端点离散化,双指针扫一下,线段树维护一下有没有点被覆盖$ geq m$次即可

    卡点:1.因为有$2 imes n$个点,所以线段树开小了一倍

    C++ Code:

    #include <cstdio>
    #include <algorithm> 
    #define maxn 500010
    using namespace std;
    const int inf = 0x3f3f3f3f;
    int n, m, tot, M, ans;
    int p[maxn << 1];
    struct interval {
    	int l, r, len;
    	bool operator < (const interval & b) const {return len < b.len;}
    } s[maxn];
    inline int min(int a, int b) {return a < b ? a : b;}
    inline int max(int a, int b) {return a > b ? a : b;}
    int V[maxn << 3], cov[maxn << 3];
    void pushdown(int rt) {
    	int &tmp = cov[rt];
    	V[rt << 1] += tmp;
    	V[rt << 1 | 1] += tmp;
    	cov[rt << 1] += tmp;
    	cov[rt << 1 | 1] += tmp;
    	tmp = 0;
    }
    void add(int rt, int l, int r, int L, int R, int num = 1) {
    	if (L <= l && R >= r) {
    		V[rt] += num;
    		cov[rt] += num;
    		return ;
    	}
    	if (cov[rt]) pushdown(rt);
    	int mid = l + r >> 1;
    	if (L <= mid) add(rt << 1, l, mid, L, R, num);
    	if (R > mid) add(rt << 1 | 1, mid + 1, r, L, R, num);
    	V[rt] = max(V[rt << 1], V[rt << 1 | 1]);
    }
    int main() {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++) {
    		scanf("%d%d", &s[i].l, &s[i].r);
    		s[i].len = s[i].r - s[i].l;
    		p[i - 1 << 1 | 1] = s[i].l;
    		p[i << 1] = s[i].r;
    	}
    	tot = n << 1;
    	sort(p + 1, p + tot + 1);
    	sort(s + 1, s + n + 1);
    	M = lower_bound(p + 1, p + tot + 1, p[tot]) - p;
    	for (int i = 1; i <= n; i++) {
    		s[i].l = lower_bound(p + 1, p + tot + 1, s[i].l) - p;
    		s[i].r = lower_bound(p + 1, p + tot + 1, s[i].r) - p;
    	}
    	int L = 1;
    	ans = inf;
    	for (int i = 1; i <= n; i++) {
    		add(1, 1, M, s[i].l, s[i].r);
    		while (V[1] >= m && L <= i) {
    			ans = min(ans, s[i].len - s[L].len);
    			add(1, 1, M, s[L].l, s[L].r, -1);
    			L++;
    		}
    	}
    	printf("%d
    ", (ans == inf) ? -1 : ans);
    	return 0;
    }
    

      

  • 相关阅读:
    写在“开张”时
    上班真累
    版本控制
    电脑主板报警声音的故障现象对照表
    js页面打开倒计时
    js中的词法分析
    修改mysql数据库密码
    上班的感受
    能力是被逼出来的!!有压力才有动力
    js中绑定事件的三种方式
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9458805.html
Copyright © 2011-2022 走看看