• 【洛谷 P1712】 [NOI2016]区间 (线段树+尺取)


    题目链接
    emmm看起来好像无从下手,
    (l_i,r_i)这么大,肯定是要离散化的。
    然后我们是选(m)个区间,我们先对这些区间按长度排个序也不影响。
    排序后,设我们取的(m)个区间的编号(b_1,b_2,...,b_m)
    (b_m)确定,我们肯定是要尽量使(b_1,b_2,...,b_{m-1})尽量接近(b_m)的,这样可使代价最小。
    所以,就可以尺取了。
    定义两个指针(l,r),首先(r)指针不停右移覆盖一遍扫到的区间直到满足条件有一个点被连续覆盖(m)次,怎么判断?显然维护一棵最大值线段树就好了。
    当满足条件,就让(l)指针右移直到不满足条件,更新答案。

    #include <cstdio>
    #include <algorithm>
    using std::sort;
    #define INF 2147483647
    const int MAXN = 650010;
    int n, m, q;
    char ch;
    inline int max(int a, int b){
    	return a > b ? a : b;
    }
    inline int min(int a, int b){
    	return a > b ? b : a;
    }
    inline int read(){
    	q = 0; ch = getchar();
    	while(ch < '0' || ch > '9') ch = getchar();
    	while(ch >= '0' && ch <= '9') { q = q * 10 + ch - '0'; ch = getchar(); }
    	return q;
    }
    struct Seg{
    	int l, r, len;
    	bool operator < (const Seg A) const{
    		return len < A.len;
    	}
    }s[MAXN];
    struct LSH{
    	int id, pos, val;
    	bool operator < (const LSH A) const{
    		return val < A.val;
    	}
    }p[MAXN << 1];
    int cnt, num;
    namespace SegTree{
        #define left (now << 1)
        #define right (now << 1 | 1)
    	int Max[MAXN << 2 << 1], lazy[MAXN << 2 << 1];
    	inline void pushup(int now){
    		Max[now] = max(Max[left], Max[right]);
    	}
    	inline void pushdown(int now){
    		if(lazy[now]){
    			Max[left] += lazy[now];
    			Max[right] += lazy[now];
    			lazy[left] += lazy[now];
    			lazy[right] += lazy[now];
    			lazy[now] = 0;
    		}
    	}
    	void update(int now, int l, int r, int wl, int wr, int p){
    		if(l >= wl && r <= wr){ Max[now] += p; lazy[now] += p; return; }
    		pushdown(now);
    		int mid = (l + r) >> 1;
    		if(wl <= mid) update(left, l, mid, wl, min(mid, wr), p);
    		if(wr > mid) update(right, mid + 1, r, max(mid + 1, wl), wr, p);
    		pushup(now);
    	}
    	int query(int now, int l, int r, int wl, int wr){
    		if(l >= wl && r <= wr) return Max[now];
    		int ans = 0;
    		pushdown(now);
    		int mid = (l + r) >> 1;
    		if(wl <= mid) ans = max(ans, query(left, l, mid, wl, min(mid, wr)));
    		if(wr > mid) ans = max(ans, query(right, mid + 1, r, max(mid + 1, wl), wr));
    		return ans;
    	}
    }using namespace SegTree;
    int ans = INF;
    int main(){
    	n = read(); m = read();
    	for(int i = 1; i <= n; ++i){
    		s[i].l = read(); s[i].r = read();
    		s[i].len = s[i].r - s[i].l;
    		p[++cnt].val = s[i].l; p[cnt].id = i; p[cnt].pos = 1;
    		p[++cnt].val = s[i].r; p[cnt].id = i; p[cnt].pos = 2;
    	} p[0].val = -1;
    	sort(p + 1, p + cnt + 1);
    	for(int i = 1; i <= cnt; ++i)
    		if(p[i].pos == 1)
    			if(p[i].val != p[i - 1].val)
    				s[p[i].id].l = ++num;
    			else s[p[i].id].l = num;
    		else
    			if(p[i].val != p[i - 1].val)
    				s[p[i].id].r = ++num;
    			else s[p[i].id].r = num;
    	sort(s + 1, s + n + 1);
    	int l = 1, r = 0;
    	while(r < n){
    		while(r < n && Max[1] < m){
    			++r;
    			update(1, 1, num, s[r].l, s[r].r, 1);
    		}
    		if(Max[1] < m) break;
    		int tmp;
    		while(Max[1] >= m) tmp = s[l].len, update(1, 1, num, s[l].l, s[l].r, -1), ++l;
    		ans = min(ans, s[r].len - tmp);
    	}
    	printf("%d
    ", ans == INF ? -1 : ans);
    	return 0;
    }
    
    
  • 相关阅读:
    版本控制系统Git
    CI框架中一个类中调用另一个类中已经加载对象测试
    关于PHP的框架
    node之http模块
    airtest之脚本批量运行
    airtest之一个脚本在多设备上运行
    npm概念
    node概念
    python -m xx.py和python xx.py的区别
    命令行运行脚本
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/9739303.html
Copyright © 2020-2023  润新知