Codeforces Round #673 (Div. 2) C. k-Amazing Numbers(思维)
题目链接:https://codeforces.com/contest/1417/problem/C
题意
给出一个大小为 $n$ 的数组 $a$,计算当 $k$ 从 $1$ 到 $n$ 取值时在所有 $k$ 长区间中出现的数的最小值。
题解
记录一个值两两间的最大距离,该距离的 $k$ 长区间及之后更长的区间都可能以该值为最小值。
Tips
注意两端的处理。
代码一
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { int n; cin >> n; vector<int> pre(n + 1), dis(n + 1); for (int i = 1; i <= n; i++) { int x; cin >> x; dis[x] = max(dis[x], i - pre[x]); pre[x] = i; } for (int i = 1; i <= n; i++) { if (pre[i]) { dis[i] = max(dis[i], n + 1 - pre[i]); } } vector<int> ans(n + 1, 1e9); for (int i = 1; i <= n; i++) { ans[dis[i]] = min(ans[dis[i]], i); } for (int i = 2; i <= n; i++) { ans[i] = min(ans[i], ans[i - 1]); } for (int i = 1; i <= n; i++) { cout << (ans[i] == 1e9 ? -1 : ans[i]) << " \n"[i == n]; } } return 0; }
代码二
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { int n; cin >> n; vector<vector<int>> pos(n + 1, {0}); for (int i = 1; i <= n; i++) { int x; cin >> x; pos[x].push_back(i); } for (int i = 1; i <= n; i++) { pos[i].push_back(n + 1); } vector<int> dis(n + 1); for (int i = 1; i <= n; i++) { if (pos[i].size() > 2) { for (int j = 1; j < int(pos[i].size()); j++) { dis[i] = max(dis[i], pos[i][j] - pos[i][j - 1]); } } } vector<int> ans(n + 1, 1e9); for (int i = 1; i <= n; i++) { ans[dis[i]] = min(ans[dis[i]], i); } for (int i = 2; i <= n; i++) { ans[i] = min(ans[i], ans[i - 1]); } for (int i = 1; i <= n; i++) { cout << (ans[i] == 1e9 ? -1 : ans[i]) << " \n"[i == n]; } } return 0; }