树状数组 之 poj 2481

来源:互联网 发布:数据透视表空白不显示 编辑:程序博客网 时间:2024/06/05 04:43
/*虽然事先知道这题可用树状数组求解,但对之前 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("\n");}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();}}
0 0
原创粉丝点击