CF1462F

Solution:

根据这道题给出的数据范围可以知道这道题肯定用的是 (mathcal{O(t*n*log(n))}) 的算法。然后呢我们可以知道很明显的一个结论,就是你需要找到一条与其他所有线段相交的最多的一条线段,计算出有多少条线段与它不相交,然后这个与它不相交的线段的数量就是答案。

考虑如何统计一条线段与其他所有线段中不相交的线段的总数。两条线段是不相交的有两种可能,如果一条线段的左端点比另一条线段的右端点还要大,那么这两条线段肯定不相交,同理如果一条线段的右端点比另一条线段的左端点还小,那么这两条线段也不想交。这时我们就可以想到二分。二分可以在 (log(n)) 的时间复杂度内完成这个统计。我们可以按上面的的思路进行两次二分,然后将这两次二分的结果加在一起就是与该线段不相交的线段的总数,具体实现过程看代码。

Code:

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c<'0' || c>'9'){if(c=='-') f=0;c=getchar();}
    while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return f?x:-x;
}
const int N=2e5+10;
struct node{int l,r;}a[N];
int T,n,ans,l[N],r[N];
signed main()
{
    T=read();
    while(T--)
    {
        n=read();
        for(int i=1;i<=n;i++) a[i].l=l[i]=read(),a[i].r=r[i]=read();
        sort(l+1,l+n+1); sort(r+1,r+n+1);
        ans=LLONG_MAX;
        for(int i=1;i<=n;i++)
        {
            int t1=upper_bound(l+1,l+n+1,a[i].r)-l;
            int t2=lower_bound(r+1,r+n+1,a[i].l)-r;
            ans=min(ans,n-t1+t2);
        }
        printf("%lld
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ForeverOIer/p/14170009.html