题目链接:http://poj.org/problem?id=2828
题意:给你一个插队的序列,问最终的序列是什么
倒着更新,对于给你的每一个人所在的位置pos,那么他的前面(包括本身)一定需要pos+1个空位,所以线段树维护空位的个数就好了,注意多组输入,注意少调用函数,会超时
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 2e5 + 10;
struct Tree {
int l, r, val;
}e[maxn << 2];
struct node {
int id, val;
}pos[maxn];
int ans[maxn];
void build(int l, int r, int cur){
e[cur].l = l;
e[cur].r = r;
e[cur].val = r - l + 1;
if(l == r)return ;
int mid = l + r >> 1;
build(l, mid, cur << 1);
build(mid + 1, r, cur << 1 | 1);
}
void update(int l, int r, int cur, int val, int id){
e[cur].val--;
if(l == r) {
ans[l] = pos[id].val;
return;
}
int mid = l + r >> 1;
if(val <= e[cur << 1].val) update(l, mid, cur << 1, val, id);
else update(mid + 1, r, cur << 1 | 1, val - e[cur << 1].val, id);
}
int main(){
int n;
while(~scanf("%d", &n)) {
build(1, n, 1);
for(int i = 1; i <= n; i++) {
scanf("%d %d", &pos[i].id, &pos[i].val);
}
for(int i = n; i >= 1; i--) {
update(1, n, 1, pos[i].id + 1, i);
}
for(int i = 1; i <= n; i++) {
printf("%d%c", ans[i], " \n"[i == n]);
}
}
return 0;
}