Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstring>
- #include <string>
- #include <vector>
- #include <map>
- #include <set>
- #include <unordered_map>
- #include <unordered_set>
- #include <algorithm>
- #include <queue>
- #include <cmath>
- #include <stdio.h>
- #define _ << " " <<
- #define debug(x) #x << " = " << x
- #define ll long long
- #define ull unsigned long long
- #define int ll
- struct line {
- int m, b;
- float l;
- bool q = false;
- int val;
- bool operator < (const line& other) const {
- if (other.q) {
- return l < other.val;
- }
- else
- return m > other.m;
- }
- };
- const double eps = 1e-9;
- const float some_very_special_value = 1234567;
- float xinter (line a, line b)
- {
- return 1. * (b.b - a.b) / (a.m - b.m);
- }
- bool rel(line a, line b, line c)
- {
- //std::cout << "xinter" _ debug(xinter(b, c)) _ debug(xinter(a, c)) << std::endl;
- //std::cout << debug(a.m) _ debug(a.b) _ debug(c.m) _ debug(c.b) << std::endl;
- if (a.m == b.m)
- return b.b > a.b;
- if (xinter(b, c) <= xinter(a, c))
- return false;
- return true;
- }
- bool rel2 (line a, line b, line c)
- {
- //std::cout << "xinter" _ debug(xinter(b, c)) _ debug(xinter(a, c)) << std::endl;
- //std::cout << debug(a.m) _ debug(a.b) _ debug(c.m) _ debug(c.b) << std::endl;
- if (xinter(a, c) <= xinter(a, b))
- return false;
- return true;
- }
- std::set<line> s;
- void push(line k)
- {
- //std::cout << "begin push" _ debug(k.m) _ debug(k.b) << std::endl;
- auto sit = s.upper_bound(k);
- auto it = sit;
- if (it != s.begin() && it != s.end()) {
- --it;
- auto it2 = sit;
- if (it2 != s.end()) {
- if (!rel(*it, k, *it2)) /* check if the lines
- on the two sides don't make us irrelevant */
- return;
- }
- }
- it = sit;
- std::vector<std::set<line>::iterator> to_remove;
- if (it != s.begin()) {
- --it;
- k.l = xinter(*it, k);
- while(it != s.begin()) {
- auto c = it;
- --it;
- if (!rel(*it, *c, k)) {
- to_remove.push_back(c);
- k.l = xinter(*it, k);
- } else {
- break;
- }
- }
- } else {
- if (it != s.end() && it->m > k.m)
- k.l = xinter(*it, k);
- else
- k.l = -100000000;
- }
- it = sit;
- if (it != s.end()) {
- auto c = it;
- ++it;
- while(it != s.end()) {
- if (!rel2(k, *c, *it)) {
- to_remove.push_back(c);
- } else {
- break;
- }
- c = it;
- ++it;
- }
- }
- for (auto x : to_remove) {
- //std::cout << "removing" << debug(x) << std::endl;
- s.erase(x);
- }
- s.insert(k);
- it = s.find(k);
- it++;
- if (it != s.end()) {
- line &l = const_cast<line&> (*it);
- l.l = xinter(k, *it);
- }
- /*
- std::cout << "##################### push" _ debug(k.l) _ debug(k.m) << std::endl;
- std::cout << "after update we have" << std::endl;
- for (auto x : s) {
- std::cout << debug(x.second.m) _ debug(x.second.b) _ debug(x.second.l) << std::endl;
- } */
- //std::cout << debug(k.l) << std::endl;
- }
- int query(int x)
- {
- /*
- std::cout << "query available are" << std::endl;
- for (auto x : s) {
- std::cout << debug(x.m) _ debug(x.b) _ debug(x.l) << std::endl;
- } */
- line k;
- k.q = true;
- k.val = x;
- auto it = s.lower_bound(k);
- //std::cout << debug(it->m) _ debug(it->b) << std::endl;
- if (it != s.begin())
- --it;
- //std::cout << "query is" _ debug(x) << std::endl;
- //std::cout << "chose" _ debug(it->m) _ debug(it->b) << std::endl;
- // if (true || it != left.end()) {
- return it->m * x + it->b;
- //} else {
- // std::cout << "WA" << std::endl;
- // std::exit(0);
- // }
- }
- const int maxn = 1e6+10;
- int d[maxn], p[maxn], t[maxn];
- int dp[maxn];
- #undef int
- int main() {
- #define int ll
- std::ios::sync_with_stdio(false);
- int n;
- scanf("%lld", &n);
- for (int i =0; i < n; i++) scanf("%lld %lld %lld", d + i, p + i, t + i);
- int dist = d[0];
- //dp[k] + p[k] + (d[i] - d[k]) * t[k]
- /* dp[i] = min(dp[k] + b[k] * a[i]) */
- dp[0] = 0;
- line k;
- k.m = t[0];
- k.b = p[0];
- push(k);
- for (int i = 1; i < n; i++) {
- dp[i] = query(dist - d[i]);
- // std::cout << debug(i) _ debug(dp[i]) << std::endl;
- k.m = t[i];
- k.b = dp[i] + p[i] - (dist - d[i]) * t[i];
- push(k);
- }
- printf("%lld\n", query(dist));
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement