【2019牛客暑期多校训练营 第七场 C题】【Governing sand】【线段树】

解决一个关于树的高度和数量的问题,通过权值线段树维护和查询,实现最小花费使最高树数量超过总树一半的目标。

题目链接:
https://ac.nowcoder.com/acm/contest/887/C
题意:
NNN颗树,第i种树有P[i]P[i]P[i]颗,高度为H[i]H[i]H[i],砍掉这种树代价为C[i]C[i]C[i]
求最小的花费,使得最高的树的数量超过剩下树总数的一半
题解:
按高度从高到低进行排序,然后用权值线段树维护。
每个高度都查询砍完需要的树的最小花费,更新答案
每次查询完当前高度,砍完当前高度的树(更新权值线段树)
代码:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define sz sizeof
#define lc u<<1
#define rc u<<1|1
#define m (l+r)/2
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> Pair;
const int MAX = 1e5 + 10;

struct SegTree {
	int l, r;
	ll n, s;
}t[500 << 2];

void build(int u, int l, int r) {
	t[u].l = l, t[u].r = r, t[u].n = t[u].s = 0;
	if (l == r)return;
	build(lc, l, m); build(rc, m + 1, r);
}

void pushup(int u) {
	t[u].n = t[lc].n + t[rc].n;
	t[u].s = t[lc].s + t[rc].s;
}

void update(int u, ll c, ll n) {
	int l = t[u].l, r = t[u].r;
	if (l == r) {
		t[u].n += n;
		t[u].s += n * c;
		return;
	}
	if (c <= m)update(lc, c, n);
	else if (c > m)update(rc, c, n);
	pushup(u);
}

ll query(int u, ll last) {
	int l = t[u].l, r = t[u].r;
	if (last <= 0)return 0;
	if (l == r)return 1ll * last * l;
	if (t[lc].n >= last)return query(lc, last);
	else return t[lc].s + query(rc, last - t[lc].n);
}

struct node {
	ll h, c, n;
	bool operator < (const node& a)const {
		return h > a.h;
	}
}a[MAX];

int n;

int main() {
#ifdef ACM_LOCAL
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	while (~scanf("%d", &n)) {
		build(1, 1, 200);
		ll tot = 0;
		for (int i = 1; i <= n; i++) {
			scanf("%lld%lld%lld", &a[i].h, &a[i].c, &a[i].n);
			update(1, a[i].c, a[i].n);
			tot += a[i].n;
		}
		sort(a + 1, a + 1 + n);
		ll minn = 1e18, pre_n = 0, pre_s = 0, now_n, now_s;
		for (int i = 1; i <= n; i++) {
			now_n = now_s = 0;
			while (i < n && a[i].h == a[i + 1].h) {
				update(1, a[i].c, -a[i].n);
				now_n += a[i].n;
				now_s += a[i].n * a[i].c;
				i++;
			}
			update(1, a[i].c, -a[i].n);
			now_n += a[i].n;
			now_s += a[i].n * a[i].c;
			minn = min(minn, query(1, tot - pre_n - 2 * now_n + 1) + pre_s);
			pre_s += now_s;
			pre_n += now_n;
		}
		printf("%lld\n", minn);
	}
	return 0;
}
带开环升压转换器和逆变器的太阳能光伏系统 太阳能光伏系统驱动开环升压转换器和SPWM逆变器提供波形稳定、设计简单的交流电的模型 Simulink模型展示了一个完整的基于太阳能光伏的直流到交流电力转换系统,该系统由简单、透明、易于理解的模块构建而成。该系统从配置为提供真实直流输出电压的光伏阵列开始,然后由开环DC-DC升压转换器进行处理。升压转换器将光伏电压提高到适合为单相全桥逆变器供电的稳定直流链路电平。 逆变器使用正弦PWM(SPWM)开关来产生干净的交流输出波形,使该模型成为研究直流-交流转换基本操作的理想选择。该设计避免了闭环和MPPT的复杂性,使用户能够专注于光伏接口、升压转换和逆变器开关的核心概念。 此模型包含的主要功能: •太阳能光伏阵列在标准条件下产生~200V电压 •具有固定占空比操作的开环升压转换器 •直流链路电容器,用于平滑和稳定转换器输出 •单相全桥SPWM逆变器 •交流负载,用于观察实际输出行为 •显示光伏电压、升压输出、直流链路电压、逆变器交流波形和负载电流的组织良好的范围 •完全可编辑的结构,适合分析、实验和扩展 该模型旨在为太阳能直流-交流转换提供一个干净高效的仿真框架。布局简单明了,允许用户快速了解信号流,检查各个阶段,并根据需要修改参数。 系统架构有意保持模块化,因此可以轻松扩展,例如通过添加MPPT、动态负载行为、闭环升压控制或并网逆变器概念。该模型为进一步开发或整合到更大的可再生能源模拟中奠定了坚实的基础。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值