poj 2828 (线段树)

来源:互联网 发布:课程云笔记源码 编辑:程序博客网 时间:2024/05/21 06:00
//思路:从最后一个人往前插,这样pos的意义就变成了,前面有多少个空位。//线段树上每个节点中存储的是当前时刻,该区间有多少空位。//如果某个人插入到pos[i],则找第pos[i]个空位置插入即可#include <iostream>using namespace std;struct node{int from, to;int cap;};const int MAX_NUM = 200002;node line[3*MAX_NUM];int pos[MAX_NUM], val[MAX_NUM], ans[MAX_NUM];int n;//建树void build_tree(int left, int right, int c){line[c].from = left;line[c].to = right;line[c].cap = right - left + 1;if (left == right) return;int mid = (left + right) / 2;build_tree(left, mid, c<<1);build_tree(mid+1, right, (c<<1)+1);}int insert(int pos){int c = 1;while (line[c].from != line[c].to){line[c].cap--; //当前节点容量减1//如果左半边容量足够大,则递归进入左半边if (line[c<<1].cap >= pos){c <<= 1;}else{pos -= line[c<<1].cap;c = ((c<<1)+1);}}//递归结束,找到插入的位置line[c].cap--;return line[c].from;}int main(){int i;while (scanf("%d", &n) != EOF){build_tree(1, n, 1);for (i = 0; i < n; ++i)scanf("%d%d", &pos[i], &val[i]);for (i = n-1; i >= 0; --i)ans[insert(pos[i]+1)] = val[i];for (i = 1; i < n; ++i)printf("%d ", ans[i]);printf("%d\n", ans[i]);}return 0;}

原创粉丝点击