题意:
有n头牛,每头牛对应一个区间[Si,Ei],如果牛j 的区间是牛i 的区间的真子集(即Si <= Sj and Ej <= Ei andEi - Si > Ej - Sj),那么就说牛i 比牛j 强壮。要你依次输出比第i头牛强壮的牛数目。
题解:
将所有的牛的E区间按从大到小排序,如果E相同则S小的排在前面。读取到第i个牛的Si和Ei,那么之前出现的牛Sj<=Si 的这些牛都比i强大了。
所以首先排序,然后树状数组中存放S坐标来算出结果。
注意:S可能为0,所以S+1处理。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e5+100;
int c[maxn];
int lowbit(int x)
{
return x & -x;
}
int sum(int x)
{
int res=0;
while(x>0)
{
res+=c[x];
x -= lowbit(x);
}
return res;
}
void add(int x,int v)
{
while(x<maxn)
{
c[x]+=v;
x+=lowbit(x);
}
}
struct node
{
int s,e,index;
bool operator < (const node& a)const
{
if(e!=a.e)
return e>a.e;
return s<a.s;
}
}cows[maxn];
int ans[maxn];//ans[i]=x; x头牛比i号牛强
int main()
{
int n;
while(cin>>n,n)
{
for(int i=1;i<=n;i++)
{
scanf("%d%d",&cows[i].s,&cows[i].e);
cows[i].s++;
cows[i].index=i;
}
sort(cows+1,cows+n+1);
memset(c,0,sizeof c);
ans[cows[1].index]=0;
add(cows[1].s,1);
for(int i=2;i<=n;i++)
{
if(cows[i].s ==cows[i-1].s &&cows[i].e==cows[i-1].e)///相同
ans[cows[i].index] = ans[cows[i-1].index];
else
ans[cows[i].index] = sum(cows[i].s);
add(cows[i].s,1);
}
for(int i=1;i<=n;i++)
{
printf("%d ",ans[i]);
}
puts("");
}
}