一.上凸包
作用:求最大值
如果不等式最后化简得到dy/dx>k,那么应该用上凸包。
上凸包特点:随x递增,斜率递减
只要找到斜率最接近k且>=k的点,即是所求最大值
struct Point {
LL x, y;//斜率=y/x
Point() {}
Point (LL X, LL Y) {x = X; y = Y;}
Point operator- (const Point &P) const {return Point (x - P.x, y - P.y);}
LL operator* (const Point &P) const {return x * P.y - y * P.x;}
} P[MX], W[MX];
int n, sz;
void solve() {
sz = 0;
//如果最后的表达式中,得到 k > s,k表示斜率,s为已知数,那么我们就维护上凸包。
/*从左往右的上凸包*/
for (int i = 1; i <= n; i++) {
P[i] = Point (i, p[i]);
while (sz >= 2 && (W[sz] - W[sz - 1]) * (P[i] - W[sz]) >= 0) sz--;
W[++sz] = P[i];
}
};
二.下凸包
作用:求最小值
如果不等式最后化简得到dy/dx<k,那么应该用下凸包。
下凸包特点:随x递增,斜率递增
只要找到斜率最接近k且<=k的点,即是所求最小值
struct Point {
LL x, y;//斜率=y/x
Point() {}
Point (LL X, LL Y) {x = X; y = Y;}
Point operator- (const Point &P) const {return Point (x - P.x, y - P.y);}
LL operator* (const Point &P) const {return x * P.y - y * P.x;}
} P[MX], W[MX];
int n, sz;
void solve() {
sz = 0;
//如果最后的表达式中,得到 k < s,k表示斜率,s为已知数,那么我们就维护下凸包。
/*从左往右的下凸包*/
for (int i = 1; i <= n; i++) {
P[i] = Point (i, p[i]);
while (sz >= 2 && (W[sz] - W[sz - 1]) * (P[i] - W[sz]) <= 0) sz--;
W[++sz] = P[i];
}
};