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
原创粉丝点击