首先算出兩個區間包含的答案,然后就可以刪掉所有被包含的區間,此時發現右端點也單調遞增
那么對於任意一種方案,假設他選擇了區間[l,r]中的某一些區間且選擇了l和r,那么一定可以等價為僅選擇l和r兩個區間,因此答案一定是選某兩個區間
簡單計算后可以發現答案有單調性,所以用優先隊列來找到上一個最大值即可
另外,算出包含區間的答案只需要:1.按照左端點從小到大,相同則右端點從大到小排序;2.對於每一個區間直接與上一個沒有被包含的區間比較並計算即可;3.雖然這樣是有反例的([1,10],[5,11]和[6,12]),但這樣前兩個一定更優)

1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1000005 4 struct ji{ 5 int x,y; 6 bool operator < (const ji &a)const{ 7 return (x<a.x)||(x==a.x)&&(y>a.y); 8 } 9 }a[N],b[N]; 10 int n,m,l,r,q[N]; 11 long long ans; 12 long long calc(int x,int y){ 13 return 1LL*(b[y].y-b[x].x)*(b[x].y-b[y].x); 14 } 15 int main(){ 16 scanf("%d",&n); 17 for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y); 18 sort(a+1,a+n+1); 19 b[m=1]=a[1]; 20 for(int i=2;i<=n;i++) 21 if (b[m].y<a[i].y)b[++m]=a[i]; 22 else ans=max(ans,1LL*(a[i].y-a[i].x)*(b[m].y-b[m].x)); 23 for(int i=2;i<=m;i++){ 24 while ((l<r)&&(calc(q[r-1],i)<calc(i-1,i)))r--; 25 q[r++]=i-1; 26 ans=max(ans,calc(q[l],i)); 27 } 28 printf("%lld",ans); 29 }