Cows
题意:John家里有好多奶牛,所有奶牛都在同一条直线上活动,第i个奶牛活动范围是[Si, Ei],对于两头奶牛i, j来说如果Si<=Sj&&Ei>=Ej&&Ej-Sj<Ei-Si 则奶牛i比奶牛j强壮,也就是说如果j的活动范围在i的活动范围内且不重合的话,奶牛i就比奶牛j强壮;对每个奶牛,求出比他强壮的奶牛的数量;
思路:再来整理一下题意:[Si, Ei]不就是一条线段嘛!也就是说当线段j是线段i的真子区间时i比j强壮;
先把E由大到小排序然后x由小到大排序,然后插入树状数组即可;
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn=100010;
int tr[maxn], ans[maxn];
struct point{
int x, y, id;
bool operator < (const point &p)const{
if(y!=p.y) return y>p.y;
return x<p.x;
}
}p[maxn];
int lowbit(int x){
return x&(-x);
}
void updata(int x){
while(x<maxn){
tr[x]++;
x+=lowbit(x);
}
}
int getsum(int x){
int s=0;
while(x>0){
s+=tr[x];
x-=lowbit(x);
}
return s;
}
int main(){
int n;
while(scanf("%d", &n), n){
int x, y;
memset(tr, 0, sizeof(tr));
for(int i=1; i<=n; i++){
scanf("%d%d", &p[i].x, &p[i].y);
p[i].x++;
p[i].y++;
p[i].id=i;
}
p[0].x=-1, p[0].y=-1;
sort(p+1, p+n+1);
memset(ans, 0, sizeof(ans));
for(int i=1; i<=n; i++){
if(p[i].x==p[i-1].x&&p[i].y==p[i-1].y) ans[p[i].id]=ans[p[i-1].id];
else ans[p[i].id]=getsum(p[i].x);
updata(p[i].x);
}
for(int i=1; i<=n; i++){
printf("%d%c", ans[i], i==n?'\n':' ');
}
}
return 0;
}