POJ
来源:互联网 发布:淘宝商品为何会下架 编辑:程序博客网 时间:2024/05/23 01:24
题意:
每个人选择一个位置进入队列,后来的人会插到先来的人前面,问最后队伍上每个人的编号是多少。
思路:
插队问题,线段树单点更新,后来的人更有主动权,所以只要倒着考虑即可。然后每次插入到当前队列的第p[i]个空位上,sum[i]表示前i个位置中还有多少个空位。
代码:
#include <cstdio>#include <cstring>#include <iostream>using namespace std;#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1const int MAXN = 2e5 + 10;int p[MAXN], v[MAXN], ans[MAXN];struct SegmentTree { int sum[MAXN << 2]; void push_up(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; } void build(int l, int r, int rt) { if (l == r) { sum[rt] = 1; return; } int m = (l + r) >> 1; build(lson); build(rson); push_up(rt); } void update(int pos, int val, int l, int r, int rt) { if (l == r) { sum[rt] = 0; ans[l] = val; return; } int m = (l + r) >> 1; if (sum[rt << 1] >= pos) update(pos, val, lson); else update(pos - sum[rt << 1], val, rson); push_up(rt); }}segtree;int main() { int n; while (scanf("%d", &n) != EOF) { segtree.build(1, n, 1); for (int i = 1; i <= n; i++) { scanf("%d%d", &p[i], &v[i]); } for (int i = n; i >= 1; i--) { segtree.update(p[i] + 1, v[i], 1, n, 1); } for (int i = 1; i <= n; i++) printf("%d%c", ans[i], i == n ? '\n' : ' '); } return 0;}
0 0