E题 双指针
注:下标从 0 开始。
单考虑从左到右,枚举 i,意味前 个数我们使用操作 1 变为红色(
的取值范围是
),后面用操作 2 来完成题意。
取值范围:因为取了 个以后,剩下一个,没必要使用操作 2。
此时可以再利用一个变量 r,双指针维护一段区间 表示一段没有重复元素的区间。
继续考虑操作 2 的使用范围,是 。
实现
用两个变量 记录使用操作 1 的代价和操作 2 的代价。
因为 表示的是取了几个数,所以在更新答案之后再将其更新为
,而
只需要在利用双指针扩展
的时候利用
更新即可。
代码
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n;
std::cin >> n;
std::vector<int> a(n); {
for (int i = 0; i < n; i ++ ) {
std::cin >> a[i];
}
}
i64 ans = 2e18;
{
std::map<int, int> Seen;
auto del = [&](int x) {
Seen[x] --;
};
auto add = [&](int x) {
if (Seen[x]) return false;
Seen[x] ++;
return true;
};
i64 Pre = 0, Suf = 1e18;
for (int i = 0, r = 0; r < n; i ++ ) {
for (; r < n; r ++) {
Suf = std::min(Suf, 1LL * a[r] * (n - r));
if (!add(a[r])) break;
}
ans = std::min(ans, Pre + Suf);
if (r == n) ans = std::min(ans, Pre);
Pre = 1LL * a[i] * (i + 1);
del(a[i]);
}
}
std::cout << ans << "\n";
return 0;
}