日常刷题2025-2-24

日常刷题2025-2-24

和+和

https://ac.nowcoder.com/acm/contest/102303/E

思路:预处理+优化枚举

A[i]:为i之前的子序列的和的最小值,B[i]:为i之后的子序列和的最小值

枚举子序列我们使用的是优先级队列

当只需要维护最大值或最小值时可以采用优先级队列。

代码

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;

void solve(){
	int n, m;
	std::cin >> n >> m;

	std::vector<i64> a(n+1), b(n+1);
	for (int i = 1; i <= n; i++) std::cin >> a[i];
	for (int i = 1; i <= n; i++) std::cin >> b[i];

	std::priority_queue<i64> q;
	std::vector<i64> A(n+1), B(n+1);
	i64 s = 0;
	for (int i = 1; i <= m; i++){
		s += a[i];
		q.push(a[i]);
	}
	A[m] = s;

	for (int i = m + 1; i <= n; i++){
		i64 tmp = q.top();
		if (tmp > a[i]){
			s -= tmp;
			s += a[i];
			q.pop();
			q.push(a[i]);
		}
		A[i] = s;
	}

	while (!q.empty()) q.pop();
	s = 0;
	for (int i = n; i >= n - m + 1; i--){
		s += b[i];
		q.push(b[i]);
	}
	B[n-m+1] = s;
	for (int i = n - m; i >= 1; i--){
		i64 tmp = q.top();
		if (tmp > b[i]){
			s -= tmp;
			s += b[i];
			q.pop();
			q.push(b[i]);
		}
		B[i] = s;
	}

	i64 ans = 1e18;
	for (int i = m; i <= n - m; i++){
		ans = std::min(ans, A[i] + B[i+1]);
	}

	std::cout << ans << '\n';

}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}
posted @ 2025-02-24 15:04  califeee  阅读(13)  评论(0)    收藏  举报