题意:有N头牛,每只牛有一个测试值[S,E],如果对于牛i和牛j来说,它们的测验值满足下面的条件则证明牛i比牛j强壮:Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj。现在已知每一头牛的测验值,要求输出每头牛有几头牛比其强壮。
给你一些区间,问,对于给出的每个区间,有多少个区间是完全包含它的。
先将S从小到大排序,E从大到小排序,这样就可以保证在放入一个区间里,前面所以放下的区间的左端点都是小于等于它的。那么,这时候查询,有多少个区间的右端点是大于等于它的右端点的,就可以得出答案。
需要注意的是,在查询的时候,如果当前区间和前面一个区间是完全相同的话,那么直接将前面的区间得到的答案赋给它就可以,不然,查询大于等于它的右端点的数目。还有就是离散化。
ac代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
struct Node{
int s,e;
int id;
}node[100005];
int ans[100005],d[100005],n;
int lowbit(int k)
{
return k&(-k);
}
bool cmp(Node a,Node b)
{
if(a.e != b.e)return a.e > b.e;
return a.s < b.s;
}
void add(int pos,int v)
{
while (pos <= n)
{
d[pos]+=v;
pos += lowbit(pos);
}
}
int read(int k)
{
int sum=0;
while(k>0){
sum+=d[k];
k-=lowbit(k);
}
return sum;
}
int main(){
while(scanf("%d",&n),n)
{
memset(ans,0,sizeof(ans));
memset(d,0,sizeof(d));
for(int i=0;i<n;i++)
{
scanf("%d%d",&node[i].s,&node[i].e);
node[i].s++;
node[i].e++;
node[i].id=i;
}
sort(node,node+n,cmp);
ans[node[0].id]=0;
add(node[0].s,1);
for(int i=1;i<n;i++)
{
if(node[i-1].s == node[i].s && node[i-1].e == node[i].e)
ans[node[i].id]=ans[node[i-1].id];
else
ans[node[i].id] = read(node[i].s);
add(node[i].s,1);
}
printf("%d",ans[0]);
for(int i=1;i<n;i++)
{
printf(" %d",ans[i]);
}
printf("\n");
}
return 0;
}