#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都相同,直接等于上一个值。*/
#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都相同,直接等于上一个值。*/