poj2828
链接:http://poj.org/problem?id=2828
题解:
初始状态
首先是插入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
#include<iostream> #include<cstdio> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int maxn=200001; int sum[maxn<<2]; int pos[maxn],val[maxn],seq[maxn]; int id; void build(int l,int r,int rt) //建树过程,跟节点为其整个区间的长度 { sum[rt]=r-l+1; if(l==r) return; int m=(l+r)/2; build(lson); build(rson); } void update(int p,int l,int r,int rt) //更新过程 { sum[rt]--; if(l==r) { id=l; return; } int m=(l+r)/2; if(sum[rt<<1]>=p) update(p,lson); else { p-=sum[rt<<1]; update(p,rson); } } int main() { int n; while(scanf("%d",&n)!=EOF) { build(1,n,1); for(int i=1;i<=n;i++) scanf("%d%d",&pos[i],&val[i]); for(int i=n;i>=1;i--) //从最后一步操作开始往上进行 { update(pos[i]+1,1,n,1); seq[id]=val[i]; } printf("%d",seq[1]); for(int i=2;i<=n;i++) printf(" %d",seq[i]); printf(" "); } return 0; }