/* 虽然事先知道这题可用树状数组求解, 但对之前 poj 2352 理解不够深刻啊。。。在被提示可以考虑排序下,才想出办法了。。。 其实和 poj 2352 解法一样,只不过不是那么明显了。 先对 e 进行从大到小排序, 如果 e 相等,对 s 进行从小到大排序。 (对于排序后的Cows,假设 以前的Cows stronger 当前Cow,则必然 当前Cows的s 大于 以前的Cows的s)=>可用树状数组进行维护 但 Wa 了几次次,原因: 若node[i].s == node[i-1].s, node[i].e == node[i-1].e 时, 则: (1)两个的 stronger_num 相等,因为不满足 stronger 要求 (题目要求:If Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj, we say that cowi is stronger than cowj. ) (2)但仍需对树状数组进行更新 (否则,之后的 Cows 的 stronger_num 会少算) */
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int MAX_E = 100005; struct node { int s, e, pos; }; node Arr[MAX_E]; int n, stronger_num[MAX_E], bit[MAX_E]; bool Cmp(const node &n1, const node &n2) { if (n1.e == n2.e) return n1.s < n2.s; else return n1.e > n2.e; } int mySum(int i) { int s = 0; while (i) { s += bit[i]; i -= (i & (-i)); } return s; } void myAdd(int i) { while (i <= MAX_E) { bit[i] += 1; i += (i & (-i)); } } void Solve() { for (int i = 1; i <= n; i++) { if ((i - 1) > 0 && (Arr[i].s == Arr[i - 1].s) && (Arr[i].e == Arr[i - 1].e)) { stronger_num[Arr[i].pos] = stronger_num[Arr[i - 1].pos]; myAdd(Arr[i].s); continue; } stronger_num[Arr[i].pos] = mySum(Arr[i].s); myAdd(Arr[i].s); } for (int i = 1; i <= n; i++) { if (i != 1) printf(" "); printf("%d", stronger_num[i]); } printf(" "); } int main() { //freopen("input.txt", "r", stdin); while (scanf("%d", &n) && n) { memset(stronger_num, 0, sizeof(stronger_num)); memset(bit, 0, sizeof(stronger_num)); int t_s, t_e; for (int i = 1; i <= n; i++) { scanf("%d %d", &t_s, &t_e); Arr[i].s = t_s + 1; Arr[i].e = t_e + 1; Arr[i].pos = i; } sort(Arr + 1, Arr + (n + 1), Cmp); Solve(); } }