You are given n segments on a line. There are no ends of some segments that coincide. For each segment find the number of segments it contains.
The first line contains a single integer n (1 ≤ n ≤ 2·105) — the number of segments on a line.
Each of the next n lines contains two integers li and ri ( - 109 ≤ li < ri ≤ 109) — the coordinates of the left and the right ends of the i-th segment. It is guaranteed that there are no ends of some segments that coincide.
Print n lines. The j-th of them should contain the only integer aj — the number of segments contained in the j-th segment.
4 1 8 2 3 4 7 5 6
3 0 1 0
3 3 4 1 5 2 6
0 1 1
给定n条线段,问每条线段包含了几条线段,先根据左端点值从大到小排序,相等按照右端点值从小到大,这样排序后前面的区间相对与后面的区间左端点可以满足条件,只需求前面的线段里有几个右端点也满足的即可,这一步可以用树状数组维护,不过这个题的右端点值范围较大,所以要先将右端点值离散化处理,在用树状数组维护
#include<bits/stdc++.h>
using namespace std;
struct node
{
int l,r;
int index;
}num[200005];
int f[200005],ans[200005],n;
int sum(int x)
{
int sum=0;
while(x>0)
{
sum+=f[x];
x-=x&-x;
}
return sum;
}
int add(int t,int x)
{
while(t<=n)
{
f[t]+=x;
t+=t&-t;
}
}
int cmp1(node u,node v)
{
if(u.l==v.l)
{
return u.r<v.r;
}
return u.l>v.l;
}
int cmp(node u,node v)
{
return u.r<v.r;
}
map<int,int>p;
int main()
{
int i;
cin>>n;
for(i=0;i<n;i++)
{
scanf("%d %d",&num[i].l,&num[i].r);
num[i].index=i;
}
int cnt=1;
sort(num,num+n,cmp);
for(i=0;i<n;i++)
{
if(!p.count(num[i].r))
{
p[num[i].r]=cnt++;
}
}
sort(num,num+n,cmp1);
for(i=0;i<n;i++)
{
ans[num[i].index]=sum(p[num[i].r]);
add(p[num[i].r],1);
}
for(i=0;i<n;i++)
{
printf("%d\n",ans[i]);
}
return 0;
}