首页 > 代码库 > 【POJ】Buy Tickets(线段树)
【POJ】Buy Tickets(线段树)
点更新用法很巧妙的一道题。倒序很容易的找到该人的位置,而update操作中需要不断的变化下标才能合理的插入。看了别人写的代码,学习了。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <map> 5 using namespace std; 6 7 const int maxn = 2e5 + 10; 8 int sumv[maxn << 2], data[maxn]; 9 10 void PushUp (int rt) {11 sumv[rt] = sumv[rt << 1] + sumv[rt << 1 | 1];12 }13 14 void build (int l, int r, int rt) {15 if (l == r) {16 sumv[rt] = 1;17 return ;18 }19 int m = (l + r) / 2;20 build (l, m, rt << 1);21 build (m + 1, r, rt << 1 | 1);22 PushUp (rt);23 }24 25 void update (int p, int v, int l, int r, int rt) {26 if (l == r) {27 data[l] = v; sumv[rt] = 0;28 return ;29 }30 int m = (l + r) >> 1;31 if (sumv[rt * 2] >= p) {32 update (p, v, l, m, rt * 2);33 } else {34 update (p - sumv[rt * 2], v, m + 1, r, rt * 2 + 1);35 }36 PushUp(rt);37 }38 39 int main () {40 pair<int, int> p[maxn];41 int n;42 while (~scanf ("%d", &n)) {43 for (int i = 0; i < n; ++ i) {44 scanf ("%d%d", &p[i].first, &p[i].second);45 }46 build (1, n, 1);47 for (int i = n - 1; i >= 0; -- i) {48 update (p[i].first + 1, p[i].second, 1, n, 1);49 }50 for (int i = 1; i <= n; ++ i) {51 if (i == 1) {52 printf ("%d", data[i]);53 } else {54 printf (" %d", data[i]);55 }56 }57 puts("");58 }59 return 0;60 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。