1. 程式人生 > >斜率優化應選擇凸包哪部分

斜率優化應選擇凸包哪部分

如果最後的表示式中,得到k>s,k表示斜率,s為某個數
那麼我們就維護上凸包。
從左往右的上凸包

struct Point {
    LL x, y;
    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]; LL A[MX]; int n, sz; LL solve() { LL ret = 0; sz = 0; for(int i = 1; i <= n; i++) { while(sz >= 2 && (P[i] - W[sz]) * (W[sz] - W[sz - 1]) <= 0) sz--; W[++sz] = P[i]; int l = 1, r = sz, m1, m2; while(l < r) { m1 = (2
* l + r) / 3; m2 = (l + 2 * r + 2) / 3; if(f(i, W[m1].x) < f(i, W[m2].x)) l = m1 + 1; else r = m2 - 1; } ret = max(ret, f(i, W[l].x)); } }

從右往左的上凸包

for(int i = n; i >= 1; i--) {
        while(sz >= 2 && (P[i] - W[sz]) * (W[sz] - W[sz - 1
]) >= 0) sz--;

如果最後的表示式中,得到k<s,k表示斜率,s為某個數
那麼我們就維護下凸包。
從左往右的下凸包

for(int i = 1; i <= n; i++) {
        while(sz >= 2 && (P[i] - W[sz]) * (W[sz] - W[sz - 1]) >= 0) sz--;

從右往左的下凸包

for(int i = n; i >= 1; i--) {
        while(sz >= 2 && (P[i] - W[sz]) * (W[sz] - W[sz - 1]) <= 0) sz--;

對於是處理字首的情況,假如題目要求得到
max(S1[r]S1[l1](l1)(S2[r]S2[l1])
l1<l2,令f(l1)<(l2),可以得到
S2[r]<((l21)S2[l2]S1[l21])((l11)S2[l1]S1[l11])l2l1
如果我們把點當作(i,(i1)S2[i1]S1[i1]),那麼其實表達的意思就是,這個位置是我們選擇的左區間l位置。
如果我們把點當作(i,iS2[i]S1[i]),那麼這個位置i代表的是l1位置。
(終於能無腦寫斜率優化了hhhh