POJ-2481

来源:互联网 发布:淘宝企业店铺转让过程 编辑:程序博客网 时间:2024/06/10 05:24

题意:给你n头牛,让你分别找出比当前这头牛强壮的有多少头。

思路:题上说牛强壮的条件是区间的左边比比它弱的牛小或是等于,区间的右边还要比比它弱的牛大或是等于,并且右边的减去左边的要大于弱的牛。我们就先按右边的数排序,然后再按排完后的顺序去往树状数组里存,用左端点做树状数组的下标,那样出现在对应的要存储的前面的数据对应的牛一定比自身强壮。

AC代码:

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=100100;int n,maxm;int l[maxn];struct node{    int x;    int y;    int num;};node t[maxn];int lowbit(int x){    return x&(-x);}void add(int x){    while(x<=maxm)    {        l[x]++;        x+=lowbit(x);    }}int sum(int x){    int cnt=0;    while(x)    {        cnt+=l[x];        x-=lowbit(x);    }    return cnt;}int cmp(struct node p,struct node q){    if(p.y!=q.y)        return p.y>q.y;    return p.x<q.x;}int main(){    while(~scanf("%d",&n)&&n)    {        memset(l,0,sizeof(l));        memset(t,0,sizeof(t));        maxm=0;        for(int i=1;i<=n;i++)        {            scanf("%d%d",&t[i].x,&t[i].y);            t[i].x++;     //防止出现0,那样会陷入死循环            t[i].y++;            t[i].num=i;            maxm=max(maxm,t[i].x);        }        sort(t+1,t+1+n,cmp);     //按右端点从大到小排序        int ans[maxn];        for(int i=1;i<=n;i++)        {            if(t[i].x==t[i-1].x&&t[i].y==t[i-1].y&&i>1)    //如果和上一头牛一样,那么就可以不用往下找了。                ans[t[i].num]=ans[t[i-1].num];            else                ans[t[i].num]=sum(t[i].x);            add(t[i].x);        }        for(int i=1;i<n;i++)        {            printf("%d ",ans[i]);        }        printf("%d\n",ans[n]);    }    return 0;}


0 0
原创粉丝点击