• 【线段树求区间第一个不大于val的值】Lpl and Energy-saving Lamps


    https://nanti.jisuanke.com/t/30996

    线段树维护区间最小值,查询的时候优先向左走,如果左边已经找到了,就不用再往右了。
    一个房间装满则把权值标记为INF,模拟一遍,注意考虑一个月内装满多个房间装满所有房间后不用再购买的情况。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    const int maxn = 100005;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    int a[maxn], St[maxn << 2], Q[maxn], ans[maxn], remain[maxn];
    void PushUp(int rt) {
    	St[rt] = min(St[rt << 1], St[rt << 1 | 1]);
    }
    void Build(int l, int r, int rt) {
    	if (l == r) {
    		St[rt] = a[l];
    		return;
    	}
    	int m = (l + r) >> 1;
    	Build(l, m, rt << 1);
    	Build(m + 1, r, rt << 1 | 1);
    	PushUp(rt);
    }
    void Update(int L, int C, int l, int r, int rt) {
    	if (l == r) {
    		St[rt] = C;
    		return;
    	}
    	int m = (l + r) >> 1;
    	if (L <= m) {
    		Update(L, C, l, m, rt << 1);
    	}
    	else {
    		Update(L, C, m + 1, r, rt << 1 | 1);
    	}
    	PushUp(rt);
    }
    int Query(int val, int L, int R, int l, int r, int rt) {
    	if (l == r) {
    		if (St[rt] <= val) {
    			return l;
    		}
    		return INF;
    	}
    	if (L <= l && R >= r) {
    		if (St[rt] > val) {
    			return INF;
    		}
    	}
    	int m = (l + r) >> 1;
    	int ANS = INF;
    	if (L <= m) ANS = min(ANS, Query(val, L, R, l, m, rt << 1));
    	if (ANS != INF) {
    		return ANS;
    	}
    	if (R > m) ANS = min(ANS, Query(val, L, R, m + 1, r, rt << 1 | 1));
    	return ANS;
    }
    int main() {
    	int n, m, q, mxq = 0;
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++) {
    		scanf("%d", &a[i]);
    	}
    	scanf("%d", &q);
    	for (int i = 1; i <= q; i++) {
    		scanf("%d", &Q[i]);
    		mxq = max(mxq, Q[i]);
    	}
    	Build(1, n, 1);
    	for (int i = 1, now = m, fin = 0; i <= mxq; i++, fin >= n ? 0 : now += m) {
    		int p = Query(now, 1, n, 1, n, 1);
    		ans[i] = ans[i - 1];
    		while (p != INF) {
    			fin++;
    			ans[i]++;
    			now -= a[p];
    			Update(p, INF, 1, n, 1);
    			p = Query(now, 1, n, 1, n, 1);
    		}
    		remain[i] = now;
    	}
    	for (int i = 1; i <= q; i++) {
    		printf("%d %d
    ", ans[Q[i]], remain[Q[i]]);
    	}
    }
  • 相关阅读:
    Python unittest单元测试框架总结
    RabbitMQ集群搭建
    mysql之mysqldump——备份与还原
    新版本Ubuntu本地提权漏洞复现
    Flash 零日漏洞复现(CVE-2018-4878)
    申论之道
    上海失业金
    C# GUID有什么用?
    C#通过接口或者父类可以调用子类的方法或者属性吗?
    C# 按逗号分隔字符串&强制类型转换string转double
  • 原文地址:https://www.cnblogs.com/stolf/p/9572833.html
Copyright © 2020-2023  润新知