poj2828

/* * poj2828.cpp * * Created on: 2010-8-11 * Author: friendy */ #include #include #include using namespace std; //又是一道线段树的题目,感觉很经典,刚开始就想着用链表,后来看到会超时,也就没写 //根本没想到会用到线段树。这个思想很奇特,从后面加进来,每个点维持前面还有多少个空位置 //最后插入的位置都是正确的位置,而如果和这个位置相同的的那么就会着这个数的后面。 // struct Tree{ int s,e,c; }tree[600001]; int value[200001]; int pre[200001][2]; void MakeTree(int a,int b,int num){//建树的过程很简单,每个点有一个左右坐标范围,还有一个就是在这个范围内有多少个空的位置 if(a==b){ tree[num].s=a; tree[num].e=b; tree[num].c=1; } else{ tree[num].s=a; tree[num].e=b; tree[num].c=b-a+1;//初始化空位置的数目 int mid=(a+b)>>1; MakeTree(a,mid,2*num); MakeTree(mid+1,b,2*num+1); } } void insert(int pos,int data,int num){//到着插入新的点。 tree[num].c--;//空位置减少一个,更新每一层 if(tree[num].s==tree[num].e){//如果到了叶子节点就直接更新 value[tree[num].s]=data; return; } if(tree[2*num].c>pos){//否则,如果要插入的位置小于当前字节点的空位置,那么就走左子树 insert(pos,data,2*num); } else{//否则走右子树 insert(pos-tree[2*num].c,data,2*num+1);//此时要更新空位置的数目 } } int main(){ int i,n; while(scanf("%d",&n)!=EOF){ MakeTree(1,n,1); for(i=0;i =0;i--){//倒着插入新节点 insert(pre[i][0],pre[i][1],1); } for(i=1;i
0
0

你可能感兴趣的:(c,tree,insert,2010)