F. Greetings

原题链接

读题

所有人的速度相同,也就是说,如果大家都在动,那么大家永不相交。所以相交的情况有且仅有b到终点了,而a还在b的后面,且a的终点在b的后面

将上述情况模型化后,就是求每个人行动的区间包含了多少人,然后对每个人求和

题解

再度简化,对于第i人来说,就是求r小于它且l大于它的人数

我们可以这样想,对r进行升序排序,然后遍历,这个时候i1所代表的是r小于其的人数,然后怎么求r小于它的人里l大于它的呢?
天才的想法:反过来求,利用前缀和,找出l小于它的人数,然后相减就是答案。前缀和用树状数组快速求解

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
    ll l;
    ll r;
    friend bool operator <(node a,node b){return a.r<b.r;}
}edge[200005];
ll l[200005]={0};
ll pres[200005]={0};
ll n;
ll lowbit(ll x)
{
    return x & -x;
}
void occur(ll x)
{
    for(ll i=x;i<=n;i+=lowbit(i))pres[i]++;
}
ll inquire(ll x)
{
    ll cnt=0;
    for(ll i=x;i>=1;i-=lowbit(i))cnt+=pres[i];
    return cnt;
}
int main()
{
    ios_base::sync_with_stdio(false);
    ll t;
    cin>>t;
    while(t--)
    {
        memset(pres,0,sizeof(pres));
        cin>>n;
        for(ll i=1;i<=n;i++)
        {
            cin>>l[i];
            cin>>edge[i].r;
            edge[i].l=l[i];
        }
        sort(l+1,l+n+1);
        sort(edge+1,edge+1+n);
        ll ans=0;
        for(ll i=1;i<=n;i++)
        {
            ll pos=lower_bound(l+1,l+1+n,edge[i].l)-l;
            ll pre=inquire(pos);
            ans+=i-1-pre;
            occur(pos);
        }
        cout<<ans<<endl;
    }
    return 0;
}

posted @   纯粹的  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示