2369. 区间
2369. 区间
决策单调性
首先我们处理区间,如果这个区间被其它区间包含,那么我们暂时不考虑它
处理完之后,所有区间呈现出\(l,r\)递增,选出的区间集合一定是一段连续的区间
然后我们决策单调性分治求解,单调性: \(j\)随\(i\)的递增而递增
对于那些被包含的区间,上面提到的情况一定不会产生贡献(取那段包含它的区间一定更优)
还有一种情况,就是被包含的区间和包含它的区间之间产生贡献,就是选一段最长的包含它的区间算贡献即可
const int N=1e6+10;
int n,m;
struct Node{
int l,r;
} A[N];
struct CMP{
bool operator () (const Node a,const Node b){
if(a.l!=b.l) return a.l<b.l;
return a.r>b.r;
}
};
inline void chk(ll &x,ll y){ ((x<y)&&(x=y)); }
inline void chk(int &x,int y){ ((x<y)&&(x=y)); }
ll ans;
void Solve(int l,int r,int L,int R){
if(l>r) return;
int mid=(l+r)>>1;
ll ma=-1e18,id=0;
rep(i,max(L,mid+1),R) {
ll t=1ll*(A[mid].r-A[i].l)*(A[i].r-A[mid].l);
((t>ma)&&(ma=t,id=i));
}
chk(ans,ma);
Solve(l,mid-1,L,id);
Solve(mid+1,r,id,R);
}
int s[N];
void Add(int p,int x) {
p++;
while(p) chk(s[p],x),p-=p&-p;
}
int Que(int p) {
p++;
int res=0;
while(p<N) chk(res,s[p]),p+=p&-p;
return res;
}
int main(){
n=rd();
rep(i,1,n) A[i].l=rd(),A[i].r=rd();
sort(A+1,A+n+1,CMP());
int ma=0;
rep(i,1,n) {
if(A[i].r<=A[i].l) continue;
if(ma<A[i].r) {
A[++m]=A[i];
ma=A[i].r;
Add(A[i].r,A[i].r-A[i].l);
} else chk(ans,1ll*Que(A[i].r)*(A[i].r-A[i].l));//被包含时,选一段最长的包含它的区间,即lj<=li
}
n=m;
Solve(1,n,1,n);
printf("%lld\n",ans);
}