可以用树状数组解决。

先按左端点递增排序,左端点相等的按右端点降序排列。

然后从左往有扫,更新答案同时更新sum数组。

对于一只Cow i,ans[i]为f(i)-g(i).

f(i)为满足p[j].s<=p[i].s&&p[j].e>=p[i].e(0<=j<n,j!=i)的Cow只数。

g(i)为满足p[j].s==p[i].s&&p[j].e==p[i].e(0<=j<n,j!=i)的Cow只数。

开个d数组维护一下,d[i]即为g(i)..

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=100005;
int sum[maxn];
int ans[maxn];
int d[maxn];
struct node{
    int s,e,id;
    bool operator<(const node& x)const{
        return s<x.s||(s==x.s&&e>x.e);
    }
}p[maxn];
int n;
int getsum(int x){
    int res=0;
    while(x)res+=sum[x],x-=x&-x;
    return res;
}
void update(int x){
    while(x<=100004)sum[x]++,x+=x&-x;
}
int main()
{
//    freopen("in","r",stdin);
    while(scanf("%d",&n)>0&&n){
        for(int i=0;i<n;i++){
            scanf("%d%d",&p[i].s,&p[i].e),p[i].id=i;
            ++p[i].s;
            ++p[i].e;
        }
        sort(p,p+n);
        memset(sum,0,sizeof sum);
        for(int i=0;i<n;i++){
            ans[p[i].id]=getsum(100004)-getsum(p[i].e-1);
            d[i]=(p[i].s==p[i-1].s&&p[i].e==p[i-1].e)?d[i-1]+1:0;
            ans[p[i].id]-=d[i];
            update(p[i].e);
        }
        for(int i=0;i<n;i++)printf("%d\n",ans[i]);
    }
    return 0;
}