题目分析
定义一个结构体Cow记录其起点、终点、id和“当前相同区间数目”(后面解释)。按照e从大到小、s从小到大的顺序排列,则对于某头牛来说,比它强壮的都排在它前面。但前面可能有与其区间相同的,于是记录前面有几头相同的牛,计算答案时删掉即可。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
struct Cow
{
int s,e,pos,same;
friend bool operator==(const Cow &x,const Cow &y)
{
return x.s==y.s&&x.e==y.e;
}
}cow[maxn];
bool cmp(Cow x,Cow y)
{
if(x.e>y.e) return true;
if(x.e==y.e && x.s<y.s) return true;
return false;
}
int ans[maxn];
int bit[maxn];
int maxb;
int n;
inline int lowbit(int x){return x&-x;}
void add(int x)
{
for(;x<=maxb;x+=lowbit(x)) bit[x]+=1;
}
int getsum(int x)
{
int res=0;
for(;x>0;x-=lowbit(x)) res+=bit[x];
return res;
}
int main()
{
while(cin>>n && n)
{
maxb=-1;
memset(bit,0,sizeof bit);
for(int i=0;i<n;i++)
{
cow[i].pos=i;
cow[i].same=0;
scanf("%d%d",&cow[i].s,&cow[i].e);
cow[i].s++;cow[i].e++;
maxb=max(maxb,cow[i].e);
}
sort(cow,cow+n,cmp);
for(int i=0;i<n;i++)
{
if(i!=0 && cow[i]==cow[i-1]) cow[i].same=cow[i-1].same;
ans[cow[i].pos]=getsum(cow[i].s)-cow[i].same;
cow[i].same++;
add(cow[i].s);
}
for(int i=0;i<n-1;i++) printf("%d ",ans[i]);
cout<<ans[n-1]<<endl;
}
return 0;
}