当前位置:   article > 正文

构造+有序集合,CF 1023D - Array Restoration

构造+有序集合,CF 1023D - Array Restoration

一、题目

1、题目描述

2、输入输出

2.1输入

2.2输出

3、原题链接

1023D - Array Restoration


二、解题报告

1、思路分析

先考虑合法性检查:

对于数字x,其最左位置和最右位置 之间如果存在数字比x小,则非法

由于q次操作,第q次操作是最后一次操作,所以数组中应该有q,即没q非法

这个合法性检查是很简单的,我们可以线段树,树状数组,分块,set……

考虑如何构造?

对于每个0,如果处于若干个数字的区间内,那么我们应该填的数字不能比这些区间中最大那个小

同时如果数组没有q,我们优先填q

算法流程:

预处理数组最大值ma,每个数字最左下标L[],最右下标R[]

遍历数组,用一个有序集合st来维护当前遇到的区间左端点

遇到0:

如果ma < q,那么我们填q,ma = q

否则,如果st非空,填st中最大那个

否则,填1

非0:

如果i == L[a[i]],a[i] 入st

如果 i == R[i], a[i] 出st

如果a[i] < min(st),非法输出NO

2、复杂度

时间复杂度: O(NlogN)空间复杂度:O(N)

3、代码详解

 ​
  1. #include <bits/stdc++.h>
  2. #define sc scanf
  3. using i64 = long long;
  4. using i128 = __int128;
  5. using PII = std::pair<int, int>;
  6. constexpr int inf32 = 1e9 + 7;
  7. constexpr i64 inf64 = 1e18 + 7;
  8. constexpr int P = 998244353;
  9. constexpr double eps = 1e-6;
  10. // #define DEBUG
  11. void solve()
  12. {
  13. int n, q;
  14. std::cin >> n >> q;
  15. std::vector<int> a(n), L(q + 1, -1), R(q + 1, -1);
  16. int ma = -1, mi = inf32;
  17. for (int i = 0; i < n; ++ i) {
  18. std::cin >> a[i], ma = std::max(ma, a[i]), mi = std::min(mi, a[i]);
  19. if (L[a[i]] == -1) L[a[i]] = i;
  20. R[a[i]] = i;
  21. }
  22. std::set<int> st;
  23. for (int i = 0; i < n; ++ i) {
  24. if (!a[i]) {
  25. if (ma < q)
  26. a[i] = q, ma = q;
  27. else if(st.size())
  28. a[i] = *std::prev(st.end());
  29. else
  30. a[i] = 1;
  31. }
  32. else {
  33. if (L[a[i]] == i && i < R[a[i]]) st.insert(a[i]);
  34. if (R[a[i]] == i && L[a[i]] < i) st.erase(a[i]);
  35. if (st.size() && a[i] < *std::prev(st.end())) {
  36. std::cout << "NO\n";
  37. return;
  38. }
  39. }
  40. }
  41. if (ma < q) {
  42. std::cout << "NO\n";
  43. return;
  44. }
  45. std::cout << "YES\n";
  46. for (int x : a)
  47. std::cout << x << ' ';
  48. }
  49. int main()
  50. {
  51. #ifdef DEBUG
  52. freopen("in.txt", "r", stdin);
  53. freopen("out.txt", "w", stdout);
  54. #endif
  55. std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
  56. int _ = 1;
  57. // std::cin >> _;
  58. while (_--)
  59. solve();
  60. return 0;
  61. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号