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; }