POJ--2481 Cows(排序+树状数组)

地址:http://poj.org/problem?id=2481

题意:n只羊,每只羊占有一个[S,E]。如果一只羊的区间囊括它,而且长度比它长,就说明这只羊比它大。求每只羊比它本身大的羊的数目。

解析:

这道题和LOJ10114数星星:https://www.cnblogs.com/liyexin/p/12853300.html 基本一致。

只是这道题需要自己排下序。

可以发现,如果把每个区间看成坐标的话,比它大的,其实就是位于它左上角的坐标点,求这个数目即可。

排序:

(x,y)。对于y不同的,直接降序排列,y相同的,x升序排列。这样判断的时候,直接看它前面的x值就可以了。

这个数目由树状数组来维护,接下来就是基本操作了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
struct node
{
    int id,x,y;
}st[maxn];
int num[maxn];
int n;
int c[maxn];
bool cmp(node a,node b)
{
    if(a.y!=b.y)
        return a.y>b.y;
    else
        return a.x<b.x;
}
int lowbit(int x)
{
    return x&(-x);
}
void update(int id)
{
    for(int i=id;i<maxn;i+=lowbit(i))
        c[i]++;
}
int getsum(int id)
{
    int ans=0;
    for(int i=id;i>=1;i-=lowbit(i))
        ans+=c[i];
    return ans;
}
int main()
{
    while(scanf("%d",&n)&&n)
    {
        for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&st[i].x,&st[i].y),st[i].id=i;
                st[i].x++;  //树状数组,不要有0
                st[i].y++;
            }
        memset(num,0,sizeof(num));
        memset(c,0,sizeof(c));
        sort(st+1,st+1+n,cmp);
        for(int i=1;i<=n;i++)
        {
            if(i!=1&&st[i].x==st[i-1].x&&st[i].y==st[i-1].y)
            {
                num[st[i].id]=num[st[i-1].id];  //相同的点,就继承它的数目就可以了。
            }
            else
            {
                num[st[i].id]=getsum(st[i].x);
            }
            update(st[i].x);
        }
        for(int i=1;i<n;i++)
            cout<<num[i]<<" ";
            cout<<num[n]<<endl;
    }
}
原文地址:https://www.cnblogs.com/liyexin/p/12994180.html