[USACO17FEB]Why Did the Cow Cross the Road III G (树状数组,排序)

题目链接

Solution

二维偏序问题。
现将所有点按照左端点排序,如此以来从左至右便满足了 \(a_i<a_j\)
接下来对于任意一个点 \(j\) ,其之前的所有节点都满足 \(a_i<a_j\) ,但是还要满足 \(a_j<b_i<b_j\)
所以可以考虑将每一个点的右端点插入树状数组,而 \([a_j,b_j]\) 之间 \(b\) 的数量即为当前点的答案。

Code

#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;
}
posted @ 2019-07-22 20:37  Kevin_naticl  阅读(190)  评论(0编辑  收藏  举报