Advertisement
Guest User

Untitled

a guest
May 21st, 2018
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.89 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4. #include <vector>
  5. #include <map>
  6. #include <set>
  7. #include <unordered_map>
  8. #include <unordered_set>
  9. #include <algorithm>
  10. #include <queue>
  11. #include <cmath>
  12. #include <stdio.h>
  13.  
  14. #define _ << " " <<
  15. #define debug(x) #x << " = " << x
  16.  
  17. #define ll long long
  18. #define ull unsigned long long
  19.  
  20. #define int ll
  21. #define float double
  22.  
  23. using namespace std;
  24. struct line {
  25. ll m, b;
  26. };
  27. struct point {
  28. double x, y;
  29. };
  30. class hullt {
  31. struct line {
  32. ll m, b, val;
  33. double xlo;
  34. bool is_query;
  35. bool query_max;
  36.  
  37. line(ll m, ll b, double val,
  38. bool is_query, bool query_max) {
  39. this->m = m;
  40. this->b = b;
  41. this->val = val;
  42. this->xlo = -std::numeric_limits<double>::max();
  43. this->is_query = is_query;
  44. this->query_max = query_max;
  45. }
  46.  
  47. bool parallel(const line &l) const {
  48. return m == l.m;
  49. }
  50.  
  51. double intersect(const line &l) const {
  52. if (parallel(l))
  53. return std::numeric_limits<double>::max();
  54. return (double)(l.b - b)/(m - l.m);
  55. }
  56.  
  57. bool operator<(const line &l) const {
  58. if (l.is_query)
  59. return query_max ? (xlo < l.val) : (l.val < xlo);
  60. return m < l.m;
  61. }
  62. };
  63.  
  64. std::set<line> hull;
  65. bool query_max;
  66.  
  67. typedef std::set<line>::iterator hulliter;
  68.  
  69. bool has_prev(hulliter it) const {
  70. return it != hull.begin();
  71. }
  72.  
  73. bool has_next(hulliter it) const {
  74. return (it != hull.end()) && (++it != hull.end());
  75. }
  76.  
  77. bool irrelevant(hulliter it) const {
  78. if (!has_prev(it) || !has_next(it))
  79. return false;
  80. hulliter prev = it, next = it;
  81. --prev;
  82. ++next;
  83. return query_max ? prev->intersect(*next) <= prev->intersect(*it)
  84. : next->intersect(*prev) <= next->intersect(*it);
  85. }
  86.  
  87. hulliter update_left_border(hulliter it) {
  88. if ((query_max && !has_prev(it)) || (!query_max && !has_next(it)))
  89. return it;
  90. hulliter it2 = it;
  91. double val = it->intersect(query_max ? *--it2 : *++it2);
  92. line l(*it);
  93. l.xlo = val;
  94. hull.erase(it++);
  95. return hull.insert(it, l);
  96. }
  97.  
  98. public:
  99. hullt(bool query_max = false) {
  100. this->query_max = query_max;
  101. }
  102.  
  103. void add_line(ll m, ll b) {
  104. line l(m, b, 0, false, query_max);
  105. hulliter it = hull.lower_bound(l);
  106. if (it != hull.end() && it->parallel(l)) {
  107. if ((query_max && it->b < b) || (!query_max && b < it->b))
  108. hull.erase(it++);
  109. else
  110. return;
  111. }
  112. it = hull.insert(it, l);
  113. if (irrelevant(it)) {
  114. hull.erase(it);
  115. return;
  116. }
  117. while (has_prev(it) && irrelevant(--it))
  118. hull.erase(it++);
  119. while (has_next(it) && irrelevant(++it))
  120. hull.erase(it--);
  121. it = update_left_border(it);
  122. if (has_prev(it))
  123. update_left_border(--it);
  124. if (has_next(++it))
  125. update_left_border(++it);
  126. }
  127.  
  128. ll get_best(ll x) const {
  129. line q(0, 0, x, true, query_max);
  130. hulliter it = hull.lower_bound(q);
  131. if (query_max)
  132. --it;
  133. return it->m*x + it->b;
  134. }
  135. };
  136.  
  137. hullt hull(false);
  138.  
  139. const int maxn = 1e6+10;
  140. int d[maxn], prep[maxn], t[maxn];
  141. int dp[maxn];
  142. #undef int
  143. int main() {
  144. #define int ll
  145. std::ios::sync_with_stdio(false);
  146.  
  147. int n;
  148. scanf("%lld", &n);
  149.  
  150. for (int i =0; i < n; i++) scanf("%lld %lld %lld", d + i, prep + i, t + i);
  151.  
  152. int dist = d[0];
  153.  
  154. //dp[k] + p[k] + (d[i] - d[k]) * t[k]
  155.  
  156. /* dp[i] = min(dp[k] + b[k] * a[i]) */
  157.  
  158. dp[0] = 0;
  159.  
  160. line k;
  161. k.m = t[0];
  162. k.b = prep[0];
  163. hull.add_line(k.m, k.b);
  164. for (int i = 1; i < n; i++) {
  165. dp[i] = hull.get_best(dist - d[i]);
  166. // std::cout << debug(i) _ debug(dp[i]) << std::endl;
  167. k.m = t[i];
  168. k.b = dp[i] + prep[i] - (dist - d[i]) * t[i];
  169. hull.add_line(k.m, k.b);
  170. }
  171.  
  172. printf("%lld\n", hull.get_best(dist));
  173.  
  174. return 0;
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement