zoukankan      html  css  js  c++  java
  • POJ2828 Buy Tickets(线段树二分)

    题目链接

    题目大意

      有n个人,依次给出这n个人进入队列时前面有多少人p[i],和它的权值v[i],求最终队列的权值序列。

    解题思路

      用线段树维护一个数组,最初全是1,代表每个位置有没有人。从后往前推,最后一个人的位置肯定是他最终的位置,然后把他删去,那么消去了最后一个人的影响,倒数第二个人的位置肯定也是他的最终位置,再把他删去。。。判断每个(pos_i)直接在线段树上二分对应的位置即可。

    代码

    const int maxn = 2e5+10;
    struct Tree {
        int sum, l, r;
    } tree[maxn<<2];
    int n, ans[maxn], a[maxn], b[maxn];
    void build(int rt, int l, int r) {
        tree[rt].l = l, tree[rt].r = r;
        if (l==r) {
            tree[rt].sum = 1; return;
        }
        int mid = (l+r)>>1;
        build(rt<<1, l, mid);
        build(rt<<1|1, mid+1, r);
        tree[rt].sum = tree[rt<<1].sum+tree[rt<<1|1].sum;
    }
    void update(int rt, int pos, int val) {
        if (tree[rt].l==tree[rt].r) {
            ans[tree[rt].l] = val;
            tree[rt].sum = 0; return;
        }
        if (tree[rt<<1].sum>=pos) update(rt<<1, pos, val);
        else update(rt<<1|1, pos-tree[rt<<1].sum, val);
        tree[rt].sum = tree[rt<<1].sum+tree[rt<<1|1].sum;
    }
    int main() {
        while(cin >> n) {
            build(1, 1, n);
            for (int i = 1; i<=n; i++) scanf("%d%d", &a[i], &b[i]);
            for (int i = n; i>=1; i--) update(1, a[i]+1, b[i]);
            for (int i = 1; i<=n; i++) printf(i==n ? "%d
    ":"%d ", ans[i]);
        }
        return 0;
    }
    
  • 相关阅读:
    4815 江哥的dp题a
    CON1023 明明的计划
    5200 fqy的难题----2的疯狂幂
    [SCOI2005] 最大子矩阵
    1457 又是求和?
    2064 最小平方数
    vijos P1459车展
    1366 xth 的第 12 枚硬币
    1360 xth 的玫瑰花
    3223: Tyvj 1729 文艺平衡树
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/13818472.html
Copyright © 2011-2022 走看看