Bootstrap

斜率优化总结

一.上凸包

作用:求最大值

如果不等式最后化简得到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];
    }
};

;