难受啊,打div3都差点掉分。这道题没做出来,以为是道线段树的题。
实际上maximal intersection应当是【右区间最小】减【左区间最大】。(也许画画图能想到)
那我们枚举把每个线段删掉后剩下的右区间最小和左区间最大就行了,方法是维护右区间第一小/第二小,左区间第一大/第二大。然后就做出来了。
#include<iostream> #define INF 2e9+10000 using namespace std; int l[300005],r[300005]; int max1=-1,max2=-1,min1=INF,min2=INF; int i1,i2; int main(){ int n; cin>>n; for(int i=1;i<=n;i++) scanf("%d%d",l+i,r+i); //最大intersection是右区间最小 - 左区间最大 for(int i=1;i<=n;i++){ if( l[i]>max1 ) { max1=l[i]; i1=i; } if( r[i]<min1 ) { min1=r[i]; i2=i; } } for(int i=1;i<=n;i++){ if( l[i]>max2 && i!=i1 ) max2=l[i]; if( r[i]<min2 && i!=i2) min2=r[i]; } int ans=0; for(int i=1;i<=n;i++){ int m1=max1,m2=min1; if( l[i]==m1 ) m1=max2; if( r[i]==m2 ) m2=min2; ans=max(ans,m2-m1); } cout<<ans; return 0; }