二维偏序问题。
现将所有点按照左端点排序,如此以来从左至右便满足了 \(a_i<a_j\) 。
接下来对于任意一个点 \(j\) ,其之前的所有节点都满足 \(a_i<a_j\) ,但是还要满足 \(a_j<b_i<b_j\) 。
所以可以考虑将每一个点的右端点插入树状数组,而 \([a_j,b_j]\) 之间 \(b\) 的数量即为当前点的答案。
#include<bits/stdc++.h>
#define N 50010
#define ll long long
using namespace std;
void in(ll &x)
{
    char ch=getchar();ll f=1,w=0;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){w=w*10+ch-'0';ch=getchar();}
    x=f*w; return;
}
ll w[N*2],n;
struct sj{
    ll l,r;
}a[N];
bool cmp(sj s,sj j ){return s.l<j.l;}
ll c[N*2];
ll lowbit(ll x){return x&(-x);}
void insert(ll x)
{
    for(int i=x;i<=2*n;i+=lowbit(i))
    c[i]++; return;
}
ll query(ll x)
{
    ll ans=0; 
    for(int i=x;i>=1;i-=lowbit(i))
    ans+=c[i]; return ans;
}
int main()
{
    //freopen("a.in","r",stdin);
    in(n);ll ans=0;
    for(ll i=1;i<=2*n;i++)
    {
        in(w[i]); 
        if(!a[w[i]].l)a[w[i]].l=i;
        else a[w[i]].r=i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        ll now=query(a[i].r)-query(a[i].l);
        ans+=now; insert(a[i].r); 
    }
    cout<<ans<<endl;
    return 0;
}[USACO17FEB]Why Did the Cow Cross the Road III G (树状数组,排序)
原文:https://www.cnblogs.com/Kv-Stalin/p/11228239.html