-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathdynamic_cht.cpp
More file actions
121 lines (115 loc) · 2.45 KB
/
dynamic_cht.cpp
File metadata and controls
121 lines (115 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
template <class T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define int long long int
#define endl '\n'
#define pb push_back
#define pf push_front
#define pi pair<int, int>
#define pii pair<int, pi>
#define fir first
#define sec second
#define MAXN 1000005
#define mod 1000000007
struct line
{
mutable int m, b, p;
bool operator<(const line &o) const
{
if (m != o.m)
return m < o.m;
return b < o.b;
}
bool operator<(const int x) const { return p < x; }
int eval(int x) const { return m * x + b; }
int inter(const line &o) const
{
int x = b - o.b, y = o.m - m;
return (x / y) - ((x ^ y) < 0 && x % y);
}
};
struct cht
{
int INF = 1e18;
multiset<line, less<>> l;
void add(int m, int b)
{
auto y = l.insert({m, b, INF});
auto z = next(y);
if (z != l.end() && y->m == z->m)
{
l.erase(y);
return;
}
if (y != l.begin())
{
auto x = prev(y);
if (x->m == y->m)
x = l.erase(x);
}
while (1)
{
if (z == l.end())
{
y->p = INF;
break;
}
y->p = y->inter(*z);
if (y->p < z->p)
break;
else
z = l.erase(z);
}
if (y == l.begin())
return;
z = y;
auto x = --y;
while (1)
{
int ninter = x->inter(*z);
if (ninter <= x->p)
x->p = ninter;
else
{
l.erase(z);
break;
}
if (x == l.begin())
break;
y = x;
x--;
if (x->p < y->p)
break;
else
l.erase(y);
}
}
int get(int x)
{
if (l.empty())
return 0;
return l.lower_bound(x)->eval(x);
}
};
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
return 0;
}
// sources:
// https://github.com/pauloamed/Training/blob/master/PD/cht.cpp
// https://github.com/brunomaletta/Biblioteca/blob/master/Codigo/DP/CHT-Dinamico.cpp
// cht dinamico
// dado uma coordenada x
// e um conjunto com varias equacoes lineares da forma: y = mx + c
// retorna o maior valor de y entre as equações do conjunto
// para o menor valor, multiplicar m e c de cada equacao por -1
// e multiplicar o resultado da query por -1
// problemas iniciais:
// https://atcoder.jp/contests/dp/tasks/dp_z
// https://codeforces.com/contest/1083/problem/E