可以用树状数组解决。
先按左端点递增排序,左端点相等的按右端点降序排列。
然后从左往有扫,更新答案同时更新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; }