题解看代码。
传送门:http://poj.org/problem?id=2828
//从后往前看。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 2000005;
struct Node {
int x,y;
int v,value;
//v存的是[x,y]区间内还有几个空位。
//(x == y)时,value存的是这个点的价值。
}t[MAXN<<2];
struct point {
int v,value;
}a[MAXN];
int n;
void Push_Up(int rt) {
t[rt].v = t[rt<<1].v + t[rt<<1|1].v;
}
void Build(int x,int y,int rt) {
t[rt].x = x; t[rt].y = y;
if(x == y) {
t[rt].v = 1;
return ;
}
int mid = (x + y) >> 1;
Build(x,mid,rt<<1);
Build(mid+1,y,rt<<1|1);
Push_Up(rt);
}
void Update(int rt,int pos,int value){
if(t[rt].x == t[rt].y) {
t[rt].v = 0;
t[rt].value = value;
return;
}
if(t[rt<<1].v >= pos) {
Update(rt<<1,pos,value);
}
else {
Update(rt<<1|1,pos-t[rt<<1].v,value);
}
Push_Up(rt);
}
void print(int rt) {
//printf("x : %d y : %d v : %d\n",t[rt].x,t[rt].y,t[rt].v);
if(t[rt].x == t[rt].y) {
printf("%d",t[rt].value);
if(t[rt].x == n) printf("\n");
else printf(" ");
return ;
}
print(rt<<1);
print(rt<<1|1);
}
void Deal_with() {
while(~scanf("%d",&n)) {
Build(1,n,1);
for(int i = 1 ; i <= n ; i++) {
scanf("%d %d",&a[i].v,&a[i].value);
a[i].v++;
//位置加1,因为我是从1开始算的
}
for(int i = n ; i >= 1 ; i--) {
Update(1,a[i].v,a[i].value);
}
print(1);
}
}
int main(void) {
//freopen("a.in","r",stdin);
Deal_with();
return 0;
}