Advertisement
libobil

Untitled

Dec 2nd, 2023
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.70 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <numeric>
  4. #include <cassert>
  5. #include <vector>
  6.  
  7. typedef long long llong;
  8. const int MAXN = 200000 + 10;
  9. const llong INF = 1e18;
  10. const int INTINF = 2e9;
  11. const int MAXSQ = 450;
  12.  
  13. struct ConvexHullTrick
  14. {
  15. struct CHTElement
  16. {
  17. llong x, y;
  18. llong to;
  19.  
  20. llong at(llong t)
  21. {
  22. return x * t + y;
  23. }
  24. };
  25.  
  26. llong intersect(CHTElement left, CHTElement right)
  27. {
  28. return (right.y - left.y) / (left.x - right.x);
  29. }
  30.  
  31. std::vector <CHTElement> cht;
  32. void push(llong x, llong y)
  33. {
  34. if (cht.size() && cht.back().y >= y)
  35. {
  36. return;
  37. }
  38.  
  39. if (cht.size()) assert(cht.back().x >= x);
  40. CHTElement newElement = {x, y, INTINF};
  41. while (cht.size() && cht.back().at(cht.back().to) <= newElement.at(cht.back().to))
  42. {
  43. cht.pop_back();
  44. }
  45.  
  46. if (cht.empty()) cht.push_back(newElement);
  47. else
  48. {
  49. cht.push_back({x, y, intersect(cht.back(), newElement)});
  50. }
  51. }
  52.  
  53. llong search(llong x)
  54. {
  55. if (cht.empty())
  56. {
  57. return -INF;
  58. }
  59.  
  60. int l = 0, r = cht.size(), mid;
  61. while (l < r - 1)
  62. {
  63. mid = (l + r) / 2;
  64. if (x <= cht[mid].to) l = mid;
  65. else r = mid;
  66. }
  67.  
  68. return cht[l].at(x);
  69. }
  70. };
  71.  
  72. int n;
  73. llong a[MAXN];
  74. bool isComposite[MAXN];
  75. ConvexHullTrick cht[MAXSQ][MAXSQ];
  76. std::vector <int> primes;
  77. llong dp[MAXN];
  78.  
  79. llong max_prize(std::vector <int> A)
  80. {
  81. n = A.size();
  82. for (int i = 1 ; i <= n ; ++i)
  83. {
  84. a[i] = A[i - 1];
  85. }
  86.  
  87. for (int i = 2 ; i * i <= n ; ++i)
  88. {
  89. if (!isComposite[i])
  90. {
  91. primes.push_back(i);
  92. for (int j = i * i ; j * j <= n ; j += i)
  93. {
  94. isComposite[j] = true;
  95. }
  96. }
  97. }
  98.  
  99. dp[1] = 0;
  100. for (const int &p : primes)
  101. {
  102. cht[p][1].push(0, dp[1]);
  103. }
  104.  
  105. llong oneAnswer = -INF;
  106. for (int i = 2 ; i <= n ; ++i)
  107. {
  108. dp[i] = -INF;
  109. if (i > 2) dp[i] = oneAnswer + a[i];
  110. if (a[i] > 0)
  111. {
  112. for (const int &p : primes)
  113. {
  114. if (cht[p][i % p].cht.empty()) continue;
  115. dp[i] = std::max(dp[i], 1LL * a[i] * (i / p) + cht[p][i % p].search(a[i]));
  116. }
  117. }
  118.  
  119. oneAnswer = std::max(oneAnswer, dp[i - 1]);
  120. if (dp[i] == -INF) continue;
  121. for (const int &p : primes)
  122. {
  123. cht[p][i % p].push(-(i / p), dp[i]);
  124. }
  125. }
  126.  
  127. return dp[n];
  128. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement