POJ 2481 Cows (树状数组)

来源:互联网 发布:linux监控tomcat进程 编辑:程序博客网 时间:2024/05/22 13:59

养了一群奶牛,奶牛有一个区间的食好,当A区间是B区间的真子集时,则B比A强,求每只奶牛比他强的有几只。
先建了一个结构体,先按区间右侧从大到小排序,相同则按左边从小到大排序。这样排序的好处在于我们无需考虑右边的影响了,只要注意区间左边就行。右边是严格不递增序列,那边左边只要越小就越强。那就查每个左区间在他之前的顺序数就行了。左右都相同情况下特判。

树状数组每次进来就查找他左边数字的个数。然后再向右更新。

#include<cstring>#include<algorithm>#include<cstdio>#include<iostream>using namespace std;#define maxn 100001int n;int c[maxn];long long ans[maxn];struct wode{    int pos,l,r;    int big;}tree[maxn];int lowbit(int x){    return x&(-x);}bool cmp(wode a,wode b){    if(a.r!=b.r)        return a.r>b.r;    return a.l<b.l;}void update(int x){    while(x<=n)    {        c[x]++;        x+=lowbit(x);    }}int query(int x){    int ans=0;    while(x)    {        ans+=c[x];        x-=lowbit(x);    }    return ans;}int main(){    while(~scanf("%d",&n),n)    {        for(int i=1;i<=n;i++)        {            scanf("%d%d",&tree[i].l,&tree[i].r);            tree[i].pos=i;            tree[i].l++,tree[i].r++;        }        sort(tree+1,tree+n+1,cmp);    //  long long ans=0;        memset(c,0,sizeof(c));        memset(ans,0,sizeof(ans));        for(int i=1;i<=n;i++)        {            if(tree[i].r==tree[i-1].r)            {                if(tree[i].l==tree[i-1].l)                    ans[tree[i].pos]=ans[tree[i-1].pos];                else ans[tree[i].pos]=query(tree[i].l);                update(tree[i].l);            }            else            {                ans[tree[i].pos]=query(tree[i].l);                update(tree[i].l);            }        }        for(int i=1;i<n;i++)        printf("%lld ",ans[i]);        printf("%lld\n",ans[n]);    }}