Nested Segments
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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.
Input
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.
Output
Print n lines. The j-th
of them should contain the only integer aj —
the number of segments contained in the j-th segment.
Examples
input
4
1 8
2 3
4 7
5 6
output
3
0
1
0
input
3
3 4
1 5
2 6
output
0
1
1
离散化+树状数组。
把所有区间按照右端点排序,然后统计左端点和右端点之间的已经包含的左端点个数,用树状数组求区间和会很快
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <stdio.h>
#include <math.h> using namespace std;
#define MAX 2*100000
struct Node
{
int l,r;
int pos;
}a[MAX+5];
int n;
int num[2*MAX+5];
int c[2*MAX+5];
int ans[MAX+5];
int s;
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int num)
{
while(x<=s)
{
c[x]+=num;
x+=lowbit(x);
}
}
int sum(int x)
{
int _sum=0;
while(x>0)
{
_sum+=c[x];
x-=lowbit(x);
}
return _sum;
}
int cmp(Node a,Node b)
{
return a.r<b.r;
}
int main()
{
scanf("%d",&n);
memset(c,0,sizeof(c));
int cnt=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].l,&a[i].r);
a[i].pos=i;
num[cnt++]=a[i].l;
num[cnt++]=a[i].r;
}
sort(num,num+cnt);
for(int i=1;i<=n;i++)
{
a[i].l=lower_bound(num,num+cnt,a[i].l)-num+1;
a[i].r=lower_bound(num,num+cnt,a[i].r)-num+1;
}
sort(a+1,a+n+1,cmp);
s=a[n].r;
for(int i=1;i<=n;i++)
{
int num=sum(a[i].r)-sum(a[i].l-1);
ans[a[i].pos]=num;
update(a[i].l,1);
}
for(int i=1;i<=n;i++)
{
printf("%d\n",ans[i]);
}
return 0;
}