Advertisement
a53

rau

a53
Mar 26th, 2020
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.50 KB | None | 0 0
  1. /**
  2. * Worg
  3. */
  4. #include <deque>
  5. #include <vector>
  6. #include <fstream>
  7. #include <algorithm>
  8.  
  9. std::ifstream fin("rau.in"); std::ofstream fout("rau.out");
  10.  
  11. const int MAX_VAL = 4e5;
  12. const int INF = 1e9;
  13.  
  14. std::deque<int> h_deque[MAX_VAL + 1];
  15. int stree[MAX_VAL * 3];
  16. std::vector<int> h, dp;
  17.  
  18. void insert_deque(int h_value, int dp_id) {
  19. while (!h_deque[h_value].empty() && dp[h_deque[h_value].back()] >= dp[dp_id]) {
  20. h_deque[h_value].pop_back();
  21. }
  22. h_deque[h_value].push_back(dp_id);
  23. }
  24.  
  25. void build_stree(int node, int left, int right) {
  26. stree[node] = INF;
  27. if (left == right) {
  28. return;
  29. }
  30.  
  31. int mid = (left + right) / 2, left_son = node * 2, right_son = node * 2 + 1;
  32. build_stree(left_son, left, mid);
  33. build_stree(right_son, mid + 1, right);
  34. }
  35.  
  36. void update_stree(int node, int left, int right, int h_value) {
  37. if (left == right) {
  38. if (h_deque[h_value].empty()) {
  39. stree[node] = INF;
  40. } else {
  41. stree[node] = dp[h_deque[h_value].front()];
  42. }
  43. return;
  44. }
  45.  
  46. int mid = (left + right) / 2, left_son = node * 2, right_son = node * 2 + 1;
  47.  
  48. if (h_value <= mid) {
  49. update_stree(left_son, left, mid, h_value);
  50. } else {
  51. update_stree(right_son, mid + 1, right, h_value);
  52. }
  53.  
  54. stree[node] = std::min(stree[left_son], stree[right_son]);
  55. }
  56.  
  57. int query_stree(int node, int left, int right, int first, int last) {
  58. if (first > last) return INF;
  59.  
  60. if (first <= left && right <= last) {
  61. return stree[node];
  62. }
  63.  
  64. int mid = (left + right) / 2, left_son = node * 2, right_son = node * 2 + 1;
  65. int answer = INF;
  66.  
  67. if (first <= mid) {
  68. answer = std::min(answer, query_stree(left_son, left, mid, first, last));
  69. }
  70. if (mid < last) {
  71. answer = std::min(answer, query_stree(right_son, mid + 1, right, first, last));
  72. }
  73. return answer;
  74. }
  75.  
  76. int solve_task(int n, int k, int c) {
  77. dp = std::vector<int>(n);
  78. dp[0] = 0;
  79. insert_deque(h[0], 0);
  80.  
  81. build_stree(1, 1, MAX_VAL);
  82. update_stree(1, 1, MAX_VAL, h[0]);
  83. for (int i = 1; i < n; i++) {
  84. // Verificam daca trebuie updatata o valoare in arborele de intervale.
  85. if (i - k - 1>= 0) {
  86. if (!h_deque[h[i - k - 1]].empty() && h_deque[h[i - k - 1]].front() == i - k - 1) {
  87. h_deque[h[i - k - 1]].pop_front();
  88. update_stree(1, 1, MAX_VAL, h[i - k - 1]);
  89. }
  90. }
  91.  
  92. // Calculam dp[i]
  93. dp[i] = INF;
  94. for (int cube_root = 0; cube_root <= 100; cube_root++) {
  95. int offset = (cube_root + 1) * (cube_root + 1) * (cube_root + 1) - 1;
  96. int left = std::max(0, h[i] - offset);
  97. int right = std::min(MAX_VAL, h[i] + offset);
  98. int candidate = query_stree(1, 1, MAX_VAL, left, right) + cube_root + c;
  99.  
  100. dp[i] = std::min(dp[i], candidate);
  101. }
  102.  
  103. // Updatam h_deque-ul corespunzator lui h[i]
  104. insert_deque(h[i], i);
  105. if (h_deque[h[i]].size() == 1) {
  106. update_stree(1, 1, MAX_VAL, h[i]);
  107. }
  108. }
  109. /*
  110. fout << "dp[] = [";
  111. for (int i = 0; i < n - 1; i++) {
  112. fout << dp[i] << ", ";
  113. }
  114. fout << dp.back() << "]\n";
  115. */
  116. return dp.back();
  117. }
  118.  
  119. int main() {
  120. int n, k, c;
  121. fin >> n >> k >> c;
  122.  
  123. h = std::vector<int>(n);
  124. for (int i = 0; i < n; i++) {
  125. fin >> h[i];
  126. }
  127.  
  128. fout << solve_task(n, k, c) << "\n";
  129. return 0;
  130. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement