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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值