bzoj2687

整体二分+决策单调性

这个方法已经忘了...

决策单调性是指dp[i]由dp[1]->dp[i-1]更新,那么当dp[j]比dp[k]优且j>k时,对于i->n j都比k优

通过这个性质我们可以把dp优化到nlogn

具体做法是整体二分

solve(l,r,L,R)表示当前对于l->r的dp决策区间在L->R

那么我们选中(l+r)/2,并且枚举所有L->R满足的决策来更新,solve(l,mid-1,L,p) solve(mid+1,r,p,R)

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
typedef long long ll;
int n;
int m;
ll ans;
struct data {
    ll l, r;
    data() {}
    data(ll _l, ll _r) : l(_l), r(_r) {}
    bool friend operator < (const data &a, const data &b) {
        return a.l == b.l ? a.r > b.r : a.l < b.l;
    }
} a[N], b[N];
ll calc(int i, int j)
{
    return (b[j].r - b[i].l)*(b[i].r - b[j].l);
}
void cdq(int l, int r, int L, int R)
{
    if(l > r) return;
    int mid = (l+r)>>1, lim = min(R, mid-1), p=mid;
    ll mx=0;
    for(int i=lim; i>=L; --i) 
    {
        ll tmp = calc(i, mid);
        if(tmp > mx)
        {
            p = i;
            mx = tmp;
        }
    }
    ans = max(ans, mx);
    cdq(l, mid - 1, L, p);
    cdq(mid + 1, r, p, R);
}
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) scanf("%d%d", &a[i].l, &a[i].r);
    sort(a + 1, a + n + 1);
    int p = 0;
    for(int i = 1; i <= n; ++i) if(a[i].r > a[p].r) b[++m] = a[i], p = i;
    else ans = max(ans, (a[p].r - a[p].l) * (a[i].r - a[i].l));
    cdq(1, m, 1, m);
    printf("%lld\n", ans);
    return 0;
}

 

posted @ 2018-01-11 18:08  19992147  阅读(87)  评论(0编辑  收藏  举报