POJ 2828 Buy Tickets

本文讨论了如何使用逆序插入算法解决POJ在线编程题2828的问题,详细介绍了算法实现过程和核心逻辑,包括节点查找、更新操作及最终结果输出。


http://poj.org/problem?id=2828

最后一个想到pos位置的人是真正站在pos位置的人 因为不会被插队,所以采用逆序插入。sum记录 该区间 目前还剩 sum个空位,每一次 query即插入的时候 ,如果该节点左儿子 sum>=pos,那么只要在左儿子找就可以了否则要在右儿子中 找 ,此时 pos 改为 pos-左儿子res,比如3但是1,2已经非空那么转到右边他只需要3 - 2 = 1个空位。

AC_CODE:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>

using namespace std;

const int MAX = 200000;

struct person{
    int pos;
    int value;
}seg[MAX];

struct node{
    int l, r, sum;
    int mid(){
        return (l + r) >> 1;
    }
}tree[MAX << 2];

int ans[MAX];
void buildtree(int l, int r, int rt){
    tree[rt].l = l;
    tree[rt].r = r;
    if(l == r){
        tree[rt].sum = 1;
        return;
    }
    int mid = tree[rt].mid();
    buildtree(l, mid, rt << 1);
    buildtree(mid + 1, r, rt << 1 | 1);
    tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
}

void update(int pos, int rt, int value){
    tree[rt].sum--;
    if(tree[rt].l == tree[rt].r){
        ans[tree[rt].l] = value;
        return;
    }
    int mid = tree[rt].mid();
    if(pos <= tree[rt << 1].sum) update(pos, rt << 1, value);
    else    update(pos - tree[rt << 1].sum, rt << 1 | 1, value);
}

int main(){
//    freopen("in.txt", "r", stdin);
    int N;
    while(scanf("%d",&N) != EOF){
        buildtree(1, N, 1);
//        memset(ans, 0, sizeof(ans));
        for(int i=1; i<=N; i++)
            scanf("%d%d",&seg[i].pos,&seg[i].value);
        for(int i=N; i>0; i--)
            update(seg[i].pos + 1, 1, seg[i].value);
        bool flag = false;
        for(int i=1; i<=N; i++){
            if(flag)    printf(" ");
            printf("%d",ans[i]);
            flag = true;
        }
        printf("\n");
    }
    return 0;
}

PS:G++TLE,C++AC! = =!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值