F. The Treasure of The Segments - 树状数组 - 离散化

Problem - F - CodeforcesF. The Treasure of The Segments

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Polycarp found nn segments on the street. A segment with the index ii is described by two integers lili and riri — coordinates of the beginning and end of the segment, respectively. Polycarp realized that he didn't need all the segments, so he wanted to delete some of them.

Polycarp believes that a set of kk segments is good if there is a segment [li,ri][li,ri] (1≤i≤k1≤i≤k) from the set, such that it intersects every segment from the set (the intersection must be a point or segment). For example, a set of 33 segments [[1,4],[2,3],[3,6]][[1,4],[2,3],[3,6]] is good, since the segment [2,3][2,3] intersects each segment from the set. Set of 44 segments [[1,2],[2,3],[3,5],[4,5]][[1,2],[2,3],[3,5],[4,5]] is not good.

Polycarp wonders, what is the minimum number of segments he has to delete so that the remaining segments form a good set?

Input

The first line contains a single integer tt (1≤t≤2⋅1051≤t≤2⋅105) — number of test cases. Then tt test cases follow.

The first line of each test case contains a single integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of segments. This is followed by nn lines describing the segments.

Each segment is described by two integers ll and rr (1≤l≤r≤1091≤l≤r≤109) — coordinates of the beginning and end of the segment, respectively.

It is guaranteed that the sum of nn for all test cases does not exceed 2⋅1052⋅105.

Output

For each test case, output a single integer — the minimum number of segments that need to be deleted in order for the set of remaining segments to become good.

Example

input

Copy

4
3
1 4
2 3
3 6
4
1 2
2 3
3 5
4 5
5
1 2
3 8
4 5
6 7
9 10
5
1 5
2 4
3 5
3 8
4 8

output

Copy

0
1
2
0

=========================================================================

直接考虑On暴力求解, 可以知道的是,我们枚举每个小区间,就能确定全部与之相交的区间个数。那么考虑如何涉及这一算法,考虑左端点从小到大排序,那么对于排在当前区间前面的,其左端点都小于等于他,我们再只需要满足左端点小于等于右端点即可保证相交,对于排在其后面的,左端点大于等于本位置左端点,我们只需要保证本位置右端点大于等于其左端点即可。那么我们可以用两个树状数组,对于“  左端点小于等于右端点即可保证相交  ” 这一条件,构造前缀树状数组,并依次添加,对于  “本位置右端点大于等于其左端点即可” 这一条件,事先构造后缀树状数组,并依次减少即可。

另外用到了离散化技巧,把左右端点全部加入离散集合。且查询大于等于一个值的时候,考虑将下标赋值为 n-pos+1,倒序存储。

#include <bits/stdc++.h>

using namespace std;
typedef long long int ll;


struct node
{
    int l,r;
};

struct node s[200000+10];

bool cmp(struct node x, struct node y)
{
    if(x.l!=y.l)
    return x.l<y.l;

    return x.r>y.r;
}
int myhash[400000+10],sum1[400000+10],sum2[400000+10];

int lowbit(int x)
{
    return x&-x;
}


int getsum1(int x)
{
    int ans=0;
    while(x)
    {
        ans+=sum1[x];
        x-=lowbit(x);
    }

    return ans;
}

int getsum2(int x)
{
    int ans=0;

    while(x)
    {
        ans+=sum2[x];
        x-=lowbit(x);
    }

    return ans;
}
void change1(int x,int val)
{
    while(x<=400000)
    {
        sum1[x]+=val;
        x+=lowbit(x);
    }
}

void change2(int x,int val)
{
    while(x<=400000)
    {
        sum2[x]+=val;
        x+=lowbit(x);
    }
}
int main()
{

   int t;
   cin>>t;

   while(t--)
   {
       int n;
       cin>>n;

       for(int i=1;i<=n;i++)
       {
           cin>>s[i].l>>s[i].r;
           myhash[i]=s[i].r;
           myhash[i+n]=s[i].l;
           sum1[i]=sum1[i+n]=sum2[i]=sum2[i+n]=0;

       }

       sort(myhash+1,myhash+1+2*n);
       sort(s+1,s+1+n,cmp);

       s[n+1].l=-1;

       for(int i=1;i<=n;i++)
       {
           int nowpos=lower_bound(myhash+1,myhash+1+2*n,s[i].l)-myhash;

           change2(nowpos,1);
       }

       int ans=1e9;
       for(int i=1;i<=n;i++)
       {
            int nowpos=lower_bound(myhash+1,myhash+1+2*n,s[i].l)-myhash;

           change2(nowpos,-1);


           int nowposr=lower_bound(myhash+1,myhash+1+2*n,s[i].r)-myhash;


           int pre=getsum1(2*n-nowpos+1);
       
           int bac=getsum2(nowposr);
         


           ans=min(ans,n-1-pre-bac);

           change1(2*n-nowposr+1,1);


       }

       cout<< ans<<endl;
   }
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qinsanma and Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值