题意:FJ有n头牛(编号为1~n),每一头牛都有一个测验值[S, E],如果对于牛i和牛j来说,它们的测验值满足下面的条件则证明牛i比牛j强壮:Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj。现在已知每一头牛的测验值,要求输出每头牛有几头牛比其强壮。
思路:树状数组。需要对牛i比牛j强壮的条件进行理解。把牛群按照测验值E的降序排序,(E相等按S的升序),那么接着就只需考虑S值,如果当前牛的测验值为[s, e],那么比它强壮的牛的个数,就等于排序在它前面的,S值在[0,s]区间的牛数量(E相等的话为[0,s-1])。下面的就是树状数组部分了。
/*
Subject: 树状数组
Sample : poj 2481 Cows -- p2352
*/
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdlib>
#include <queue>
#include <algorithm>
#define Bug cout << "here\n";
using namespace std;
const int N = 100005;
int n, T, k;
int f[N];
int cnt[N];
int B[N];
struct node {
int x, y;
int id;
}p[N];
bool cmp(const node a, const node b) {
if(a.y != b.y) return a.y > b.y;
return a.x < b.x;
}
int lowbit(int x) {
return x & (-x);
}
void add(int i, int x) {
while(i <= N) { // 注意, 不是 n, 是 N
B[i] += x;
i = i + lowbit(i);
}
} //得到 Bn
long long getsum(int i) {
long long sum = 0;
while(i > 0) {
sum += B[i];
i = i - lowbit(i);
}
return sum;
}
int main() {
int i;
while(scanf("%d", &n) == 1 && n) {
memset(cnt, 0, sizeof(cnt));
memset(B, 0, sizeof(B));
memset(f, 0, sizeof(f));
for(i = 0; i < n; i++) {
scanf("%d%d", &p[i].x, &p[i].y);
p[i].id = i;
}
sort(p, p+n, cmp);
for(i = 0; i < n; i++) {
if(i > 0 && p[i].x == p[i-1].x && p[i].y == p[i-1].y) {
f[p[i].id] = f[p[i-1].id];
}
else f[p[i].id] = getsum(p[i].x+1);
add(p[i].x+1, 1);
}
for(i = 0; i < n; i++) {
if(i == 0) cout << f[i];
else cout << ' ' << f[i];
}
cout << endl;
}
//system("pause");
return 0;
}