/*
* 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
poj2828
最新推荐文章于 2022-04-28 09:28:59 发布
本文介绍了一种使用线段树解决动态插入问题的方法。通过维护每个节点前面的空位数量,可以确保元素被正确地放置,并且相同元素将位于已有元素之后。文章详细解释了构建线段树、插入操作的具体步骤。
420

被折叠的 条评论
为什么被折叠?



