poj 2828 线段树(单点更新,逆序插入)

来源:互联网 发布:recyclerview清空数据 编辑:程序博客网 时间:2024/06/14 22:31

点击打开链接

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio> using namespace std;const int M=200005;int seg[M<<2];//存区间的空位置数 int ans[M];//记录最终位置 void Push_Up(int rt){seg[rt]=seg[rt<<1]+seg[rt<<1|1];}void build(int l,int r,int rt){if(l==r){seg[rt]=1;return;}int m=(l+r)>>1;build(l,m,rt<<1);build(m+1,r,rt<<1|1);Push_Up(rt);//左右儿子建完后 更新父节点 }void update(int p,int v,int l,int r,int rt){if(l==r){ans[l]=v;seg[rt]=0;return;}int m=(l+r)>>1;if(seg[rt<<1]>=p){update(p,v,l,m,rt<<1);}else{update(p-seg[rt<<1],v,m+1,r,rt<<1|1);//p:整个线段的第p个空位 }Push_Up(rt);}int main(){int p[M],v[M];int n;while(cin>>n){build(1,n,1);for(int i=1;i<=n;i++){scanf("%d%d",&p[i],&v[i]);}for(int i=n;i>=1;i--)//思路:最后一个人插入的位置后,该位置固定,所以则从后往前推出答案 ,pos为整个线段的第pos个空位 {update(p[i]+1,v[i],1,n,1);//pos可以看做整个线段的第pos个空位 //则pos要么等于p(p为空时) 要么在大于p(p有人则往后走) }for(int i=1;i<=n;i++){cout<<ans[i]<<" ";}cout<<endl;}return 0;} 


0 0
原创粉丝点击