日常刷题2025-2-24
日常刷题2025-2-24
和+和
思路:预处理+优化枚举
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;
}

浙公网安备 33010602011771号