zoukankan      html  css  js  c++  java
  • 洛谷P1712[NOI2016]区间

    线段树+尺取法。
    我们先离散化一次,然后按照区间长度排序,每次一位一位往后移。
    至于如何判断覆盖了多少个点,我们用一个线段树维护即可。

    My Code:

    #include <bits/stdc++.h>
    #define il inline
    #define temp template<class T>
    #define lson(o) (o << 1)
    #define rson(o) (o << 1 | 1)
    const int INF = 0x3f3f3f3f;
    const int MAXN = 5e5 + 10;
    using namespace std;
    temp il void rd(T& res) {
    	res = 0;char c;bool sign = 0;
    	for(c = getchar();!isdigit(c);c = getchar()) sign |= c == '-';
    	for(;isdigit(c);c = getchar()) res = (res << 1) + (res << 3) + (c ^ 48);
    	(sign) && (res = -res);
    	return;
    }
    temp il T _min(T x,T y) {
    	return x < y ? x : y;
    }
    temp il T _max(T x,T y) {
    	return x > y ? x : y;
    }
    int l[MAXN << 1],r[MAXN << 1];
    int n,m,i,j,k,cnt,tot,Max;
    struct Node {
    	int len,id;
    }a[MAXN << 2];
    struct LSH {
    	int x,id;
    }b[MAXN << 2];
    int tr[MAXN << 3],tag[MAXN << 3];
    il bool cmpN(Node a,Node b) {
    	return a.len < b.len;
    }
    il bool cmpL(LSH a,LSH b) {
    	return a.x < b.x;
    }
    il void pushup(int o) {
    	tr[o] = _max(tr[lson(o)],tr[rson(o)]);
    	return;
    }
    il void init(int o,int l,int r,int val) {
    	tr[o] += val;
    	tag[o] += val;
    	return;
    }
    il void pushdown(int o,int l,int r) {
    	if(tag[o]) {
    		int mid = l + r >> 1;
    		init(lson(o),l,mid,tag[o]);
    		init(rson(o),mid + 1,r,tag[o]);
    		tag[o] = 0;
    	}
    	return;
    }
    void modify(int ml,int mr,int l,int r,int o,int val) {       
    	if(l > mr || r < ml) return;
    	if(ml <= l && r <= mr) {
    		tr[o] += val;
    		tag[o] += val;
    		return;
    	}
    	pushdown(o,l,r);
    	int mid = l + r >> 1;
    	if(ml <= mid) modify(ml,mr,l,mid,lson(o),val);
    	if(mid < mr)  modify(ml,mr,mid + 1,r,rson(o),val);
    	pushup(o);
    	return;
    }
    int main() {
    	rd(n);rd(m);
    	for(int i = 1,rl,rr;i <= n;i++) {
    		rd(rl);rd(rr);
    		a[i].len = rr - rl;a[i].id = i;
    		b[++cnt].x = rl;b[cnt].id = i;
    		b[++cnt].x = rr;b[cnt].id = i;
    	}
    	sort(b + 1,b + cnt + 1,cmpL);b[0].x = -1;
    	for(int i = 1;i <= cnt;i++) {
    		if(b[i].x != b[i - 1].x) tot++;
    		if(!l[b[i].id]) l[b[i].id] = tot;   
    		else r[b[i].id] = tot; 
    	}
    	Max = tot;int sl = 0,sr = 0,ans = INF;
    	sort(a + 1,a + n + 1,cmpN);
    	while(1) {
    		while(tr[1] < m && sr <= n) {    
    			sr++;
    			int x = l[a[sr].id],y = r[a[sr].id];
    			modify(x,y,1,Max,1,1);
    		}
    		if(tr[1] < m) break;
    		while(tr[1] >= m && sl <= n) {
    			sl++;int x = l[a[sl].id],y = r[a[sl].id];
    			modify(x,y,1,Max,1,-1);
    		}
    		ans = _min(ans,a[sr].len - a[sl].len);
    	}
    	ans != INF ? printf("%d
    ",ans) : puts("-1");
    	return 0;
    } 
    
  • 相关阅读:
    当程序员的那些狗日日子
    程序员常犯的几个错误
    我没有帮你的义务,却有拒绝你的权力
    并发 并行 同步 异步 多线程的区别
    cookie的存取
    sqlserver 处理百万级以上的数据处理与优化
    为什么 jmeter 分布式测试,一定要设置 java.rmi.server.hostname
    详细解析 nginx uri 如何匹配 location 规则
    mysql innodb 从 ibd 文件恢复表数据
    mysql 从 frm 文件恢复 table 表结构的3种方法
  • 原文地址:https://www.cnblogs.com/Sai0511/p/10362905.html
Copyright © 2011-2022 走看看