【POJ】Buy Tickets(线段树)

时间:2023-07-22 12:01:38

点更新用法很巧妙的一道题。倒序很容易的找到该人的位置,而update操作中需要不断的变化下标才能合理的插入。看了别人写的代码,学习了。

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
using namespace std; const int maxn = 2e5 + ;
int sumv[maxn << ], data[maxn]; void PushUp (int rt) {
sumv[rt] = sumv[rt << ] + sumv[rt << | ];
} void build (int l, int r, int rt) {
if (l == r) {
sumv[rt] = ;
return ;
}
int m = (l + r) / ;
build (l, m, rt << );
build (m + , r, rt << | );
PushUp (rt);
} void update (int p, int v, int l, int r, int rt) {
if (l == r) {
data[l] = v; sumv[rt] = ;
return ;
}
int m = (l + r) >> ;
if (sumv[rt * ] >= p) {
update (p, v, l, m, rt * );
} else {
update (p - sumv[rt * ], v, m + , r, rt * + );
}
PushUp(rt);
} int main () {
pair<int, int> p[maxn];
int n;
while (~scanf ("%d", &n)) {
for (int i = ; i < n; ++ i) {
scanf ("%d%d", &p[i].first, &p[i].second);
}
build (, n, );
for (int i = n - ; i >= ; -- i) {
update (p[i].first + , p[i].second, , n, );
}
for (int i = ; i <= n; ++ i) {
if (i == ) {
printf ("%d", data[i]);
} else {
printf (" %d", data[i]);
}
}
puts("");
}
return ;
}