线段树结点存储的是当前区域的空位置数量。
附带上前人的图 更新讲的很明白了
初始状态
首先是插入3 69
1,4结点有4个位置,
1,2结点有2个位置,小于3,因此放到1,4结点右孩子,且1,4结点空位置减1
到了1,4右孩子后,只要找到第3-2=1个位置即可,而3,4结点的左孩子3,3含有1个空位置,1>=1,所以放到3,3位置了。
插入2 33
★关键是这里如何处理★
插入2 51
此时1,4的左孩子只有1个位置,1<2,所以只能放到1,4的右孩子3,4上
3,4的左孩子有0个位置,所以只能放在3,4的右孩子4,4上。
插入1 77
/*************************
* Author:fisty
* Data:2014-10-4
* poj2828
* 线段树,逆序更新
* **********************/
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define MAX_N 200011
#define lson l, m, k << 1
#define rson m+1, r, k << 1 | 1
int id, dat[MAX_N << 2];
struct segtree{
void build(int l,int r,int k){
int m = (l + r) >> 1;
dat[k] = r-l+1;
if(l == r)
return;
build(lson);
build(rson);
}
void update(int p, int l, int r, int k){
dat[k]--;
int m = (l + r) >> 1;
if(l == r){
id = l;
return;
}
if(p <= dat[k<<1]){
update(p,lson);
}else{
p -=dat[k<<1];
update(p,rson);
}
}
}seg;
int main(){
//freopen("in", "r", stdin);
int n;
int pos[MAX_N], val[MAX_N];
while(scanf("%d", &n) != EOF){
seg.build(1, n, 1);
int a[MAX_N];
for(int i = 1;i <= n; i++)
scanf("%d%d", &pos[i], &val[i]);
for(int i = n; i >= 1; i--){
seg.update(pos[i]+1, 1, n, 1);
a[id] = val[i];
}
for(int i = 1;i <= n; i++)
printf("%d%c", a[i],(i == n) ? '\n' : ' ');
}
return 0;
}