• [NOI2016]区间


    传送门

    Analysis

    首先对坐标离散化,注意预先存储原长度
    考虑对长度从小到大排序,然后(2 Pointers)扫描,右端不断加入区间并覆盖相应长度,当某一时刻存在点被覆盖(m)次时更新答案,并同时移动左指针(左端在移动的过程中可能有多次更新答案的机会)到第一个不满足被覆盖(m)次的区间
    由于先前对坐标进行了离散化,对点被覆盖次数的维护用线段树进行,区间加区间(max)

    Code

    #include<bits/stdc++.h>
    using namespace std;
    inline int read() {
    	int cnt = 0, f = 1; char c = getchar();
    	while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
    	while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + (c ^ 48); c = getchar();}
    	return cnt * f;
    }
    const int N = 5 * (int)1e5 + 10;
    const int INF = (int)1e9 + 7;
    int n, m, pos = 1;
    int b[N << 1], tot, ans = INF, q;
    struct node {
    	int l, r;
    	int tag, gmax;
    	#define l(p) tree[p].l
    	#define r(p) tree[p].r
    	#define tag(p) tree[p].tag
    	#define gmax(p) tree[p].gmax
    	#define ls p << 1
    	#define rs p << 1 | 1
    }tree[N << 4];
    struct node2 {
    	int l, r;
    	int len;
    }a[N];
    
    bool cmp(node2 a, node2 b) {
    	return a.len < b.len;
    }
    void pushup(int p) {gmax(p) = max(gmax(ls), gmax(rs));}
    void pushadd(int p, int d) {tag(p) += d, gmax(p) += d;}
    void pushdown(int p) {if (tag(p)) pushadd(ls, tag(p)), pushadd(rs, tag(p)), tag(p) = 0;}
    void build(int p, int l, int r) {
    	l(p) = l, r(p) = r;
    	if (l == r) {gmax(p) = 0; return;}
    	int mid = (l + r) >> 1;
    	build(ls, l, mid);
    	build(rs, mid + 1, r);
    	pushup(p);
    }
    void modify(int p, int l, int r, int d) {
    //	cout << p << ' ' <<  l(p) << ' ' << r(p) << endl;
    	if (l <= l(p) && r >= r(p)) {pushadd(p, d); return;}
    	pushdown(p);
    	int mid = (l(p) + r(p)) >> 1;
    	if (l <= mid) modify(ls, l, r, d);
    	if (r > mid) modify(rs, l, r, d);
    	pushup(p);
    }
    void init() {
    	sort (b + 1, b + tot + 1);
    	q = unique(b + 1, b + tot + 1) - b - 1;
    	for (register int i = 1; i <= n; ++i) a[i].l = lower_bound(b + 1, b + q + 1, a[i].l) - b;
    	for (register int i = 1; i <= n; ++i) a[i].r = lower_bound(b + 1, b + q + 1, a[i].r) - b; 
    }
    int main() {
    //	freopen("1.in", "r", stdin);
    	n = read(), m = read();
    	for (register int i = 1; i <= n; ++i) a[i].l = read(), a[i].r = read(), a[i].len = a[i].r - a[i].l, b[++tot] = a[i].l, b[++tot] = a[i].r;
    	init();
    	sort (a + 1, a + n + 1, cmp);
    	build(1, 1, q);
    	for (register int i = 1; i <= n; ++i) {
    		modify(1, a[i].l, a[i].r, 1);
    		while (gmax(1) >= m && pos < i) ans = min(ans, (a[i].len - a[pos].len)), modify(1, a[pos].l, a[pos].r, -1), ++pos;
    	} printf(ans == INF ? "-1" : "%d", ans);
    	return 0;
    }
    
  • 相关阅读:
    练习 : Flink 自定义Process_State 使用 OnTimer 连续3s大于70度 传感器报警
    练习 : 用 utils 读 存 kafak,flink sql 查询
    9. 查询user_info表中info:age大于等于18的记录
    练习: Flink Sink 将数据 保存 到 HDFS MySQL
    HBase Java API to Uitl
    练习:Flink 自定义 process 和 source
    ClickHouse 安装
    练习 : Flink TimeWindow 滑动 滚动 窗口 增量 全量 统计
    练习 : Flink 水位线 Flink_Watermark_Test
    Flink pom.xml
  • 原文地址:https://www.cnblogs.com/kma093/p/12992588.html
Copyright © 2020-2023  润新知