首页 > 其他 > 详细

[线段树]poj 2828

时间:2014-11-27 02:15:28      阅读:190      评论:0      收藏:0      [点我收藏+]

题意

??????n个人插队,每次某个人都会选择插入第i个人背后,输出最终的排队序列。

思路

?????建立一颗线段树,节点val值为,这个区间的空位数,然后从后向前更新线段树,也就是说,如果一个节点无法插入当前位置,那么就选择右侧最靠近这个节点的位置

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int nMax = 200010;
struct{
    int l,r,val;
}node[nMax*3];
void build(int l, int r,int u){
    node[u].l = l;
    node[u].r = r;
    node[u].val = r - l + 1;
    if(r == l)return;
    else{
        int m = (l + r) >> 1;
        build(l , m , u*2);
        build(m+1 , r , u*2 + 1);
    }

}

int id;
void update(int p ,int u){
    int l = node[u].l;
    int r = node[u].r;
    node[u].val -= 1;
    if(l == r){
        id = l;
        return;
    }
    if(p <= node[2*u].val){
        update(p , u*2);
    }else{
        update(p-node[2*u].val,u*2+1);
    }

}

int loc[nMax],val[nMax],ans[nMax];
int main(){
    int n,i;
    while(scanf("%d",&n)!=EOF){
        for(i=1 ; i <= n; i++){
            scanf("%d%d",&loc[i],&val[i]);
        }
        build(1, n, 1);
        for(i=n ; i >= 1 ; i--){
            update(loc[i]+1 , 1);
            ans[id] = val[i];
        }
        for(i = 1; i < n; i++){
            printf("%d ",ans[i]);
//            cout<<ans[i]<<" ";
        }printf("%d\n",ans[i]);
    }
    return 0;
}

?

[线段树]poj 2828

原文:http://bbezxcy.iteye.com/blog/2161055

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!