poj2481

来源:互联网 发布:python import thread 编辑:程序博客网 时间:2024/06/10 15:39
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#define MAX 100005


using namespace std;


struct cow
{
    int x,y,id;
}a[MAX];


int c[MAX],ans[MAX];


bool cmp(cow a,cow 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 add(int po,int val)
{
    while (po<=MAX)
    {
        c[po]+=val;
        po+=lowbit(po);
    }
}


int getsum(int po)
{
    int sum=0;
    while (po>0)
    {
        sum+=c[po];
        po-=lowbit(po);
    }
    return sum;
}


int main()
{
    int n;
    freopen("in.txt","r",stdin);
    while (cin>>n)
    {
        if (n==0) break;
        int i;
        memset(c,0,sizeof(c));
        memset(ans,0,sizeof(ans));
        for (i=1;i<=n;i++)
          {
              scanf("%d%d",&a[i].x,&a[i].y);
              a[i].x++;a[i].y++;
              a[i].id=i;
          }
        sort(a+1,a+n+1,cmp);
        for (i=1;i<=n;i++)
        {
           if (i==1)
           {
               ans[a[i].id]=getsum(a[i].x);
               add(a[i].x,1);
           }
           else
           {
               if (a[i].x==a[i-1].x&&a[i].y==a[i-1].y)
                   ans[a[i].id]=ans[a[i-1].id];            //若x,y都相同,直接等于上一个值。
               else ans[a[i].id]=getsum(a[i].x);
               add(a[i].x,1);                              //不论如何,都要add
           }


        }
        for (i=1;i<=n-1;i++) printf("%d ",ans[i]);
        printf("%d\n",ans[n]);
    }
    return 0;
}
/*题目大意:给你很多线段的头S和尾E,问每一条线段中包含了多少个线段,(S和E相同不计在内)。
树状数组:把线段的s和e当做是(s,e)一个点,题目要求就会变成:问每一个点的左上角有多少个点?
        就和stars一样,stars那题是问左下角有多少个点,而这题是问左上角,而且点不是有序排好的,所以有些不同。
        排序的时候先y由大到小排,先确保前面的点在后面的点的上面,
        y相同时x由小到大排,因为要求前面有多少比当前小的数,即在左边,
        若x,y都相同,直接等于上一个值。*/
0 0