将点排序后,用二分找出线段两个端点在a数组的位置,将线段的末尾端点标1,用树状数组求出区间和,最后再按原先顺序输出。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <bitset>
#include <map>
#include <string>
#include <algorithm>
#define Si(a) scanf("%d",&a)
#define Sl(a) scanf("%lld",&a)
#define Sd(a) scanf("%lf",&a)
#define Ss(a) scanf("%s",a)
#define Pi(a) printf("%d\n",(a))
#define Pl(a) printf("%lld\n",(a))
#define Pd(a) printf("%lf\n",(a))
#define Ps(a) printf("%s\n",(a))
#define W(a) while(a--)
#define mem(a,b) memset(a,(b),sizeof(a))
#define inf 0x3f3f3f3f
#define maxn 200010
#define mod 1000000007
#define PI acos(-1.0)
#define LL long long
using namespace std;
struct node
{
int l,r,ans,id;
}p[2*maxn];
int n,top=0;
int c[2*maxn];
int a[2*maxn];
bool cmp1(node a,node b)
{
return a.l<b.l;
}
bool cmp2(node a,node b)
{
return a.id<b.id;
}
int update(int i,int x)
{
while(i<=2*n)
{
c[i]+=x;
i+=(i&(-i));
}
}
int Sum(int pos)
{
int sum=0;
while(pos>0)
{
sum+=c[pos];
pos-=(pos&(-pos));
}
return sum;
}
int main()
{
Si(n);
mem(c,0);
int i;
for(i=1;i<=n;i++)
{
int l,r;
Si(l);Si(r);
a[top++]=l;
a[top++]=r;
p[i].l=l;
p[i].r=r;
p[i].id=i;
}
sort(a,a+top);
for(i=1;i<=n;i++)
{
p[i].l=upper_bound(a,a+top,p[i].l)-a;
p[i].r=upper_bound(a,a+top,p[i].r)-a;
}
sort(p+1,p+n+1,cmp1);
for(i=1;i<=n;i++)update(p[i].r,1);
for(i=1;i<=n;i++)
{
if(p[i].l+1>p[i].r-1)p[i].ans=0;
else
{
p[i].ans=Sum(p[i].r-1)-Sum(p[i].l+1);
}
update(p[i].r,-1);
}
sort(p+1,p+n+1,cmp2);
for(i=1;i<=n;i++)
Pi(p[i].ans);
return 0;
}