题意:n 个牛,每个牛在一条数轴上控制的范围是[a, b],如果牛 1 控制的范围完全包括了牛 2(除了范围完全相等的情况),那么称牛 1 比牛 2 强壮。给出 n 个牛控制的范围,按照顺序输出每个牛比几个牛强壮。
典型的树状数组题,由于 sum 函数只能控制一个因子,所以我们按照每个牛的右端点从大到小排序(相等时按照左端点从小到大),用前缀和解决左端点就可以了。需要注意的是要讨论一下两个牛的控制范围完全相等的情况。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
using namespace std;
int n, q;
int a[100005];
int b[100005];
struct node{
int x, y, id;
}N[100005];
bool cmp(node a, node b){
if(a.y == b.y) return a.x < b.x;
else return a.y > b.y;
}
int lowbit(int x){
return x&(-x);
}
void add(int pos, int num){
while(pos <= n){
a[pos] += num;
pos += lowbit(pos);
}
}
int sum(int n){
int sum = 0;
while(n > 0){
sum += a[n];
n -= lowbit(n);
}
return sum;
}
int main(){
//freopen("a.txt", "r", stdin);
while(~scanf("%d", &q) && q){
memset(a, 0, sizeof(a));
n = 0;
for(int i = 1; i <= q; i++){
int a, b;
scanf("%d %d", &a, &b);
N[i].id = i;
N[i].x = a+1;
N[i].y = b+1;
n = max(n, N[i].y);
}
sort(N+1, N+1+q, cmp);
//for(int i = 1; i <= q; i++)
//cout << N[i].id << " " << N[i].x << " " << N[i].y << endl;
N[0].x = -1;
N[0].y = -1;
for(int i = 1; i <= q; i++){
if(N[i-1].x == N[i].x && N[i-1].y == N[i].y){
add(N[i].x, 1);
b[N[i].id] = b[N[i-1].id];
}
else{
b[N[i].id] = sum(N[i].x);
add(N[i].x, 1);
}
}
for(int i = 1; i <= q; i++){
cout << b[i];
if(i != q) cout << " ";
}
cout << endl;
}
return 0;
}