poj 3278,poj1208
很多人说这个问题的思路很精妙。给我点个赞。
假设有n个人插队,给定插队顺序,他们插队的位置和每个人的val,求出插队后队伍每个位置的val。
一般来说,插入这种东西是向后推的。
对于第I个人来说,他插队的时候,前面已经满了,所以他前面应该还有一个pos的人。
但是I后面有人可能插在I前面,也就是说向后推的时候,I前面不仅有pos个体,
但可以说,I前面是有pos空位的,这些空位就是站在I前面的人的位置。
所以可以用段树来维护一个序列,每个序列存储当前情况下第j个位置之前有多少空位。
那么,对于I,求J使pos=g[j],求的方法是用线段树求。事实上,它应该大致看起来像一个二叉查找树==。
我在代码中维护的是j位置有多少空缺,所以当寻找pos时,pos 1
#包含stdio.h
#定义埃尔松左,中,右*2
#定义rson mid 1,r,rt*2 1
#定义X 200010
int g[X*4],ll,rr,val
int a[X],b[X],as[X];
无效上推(中间rt){
g[rt]=g[rt * 2]g[rt * 2 1];
void build(整数,整数,整数){
if(l==r){ g[rt]=1;返回;}
int mid=l r 1;
建设(埃尔松);
构建(rson);
俯卧撑(rt);
void update(int sum,int l,int r,int rt){
if(l==r){ g[rt]=0;as[l]=val;返回;}
int mid=l r 1;
if(sum=g[rt*2])update(sum,埃尔松);
else update(sum-g[rt*2],rson);
俯卧撑(rt);
int main(){
int i,j,n;
while(~scanf(%d ,n)){
build(1,X,1);
for(I=1;我我)
scanf(%d%d ,a[i],b[I]);
for(I=n;我我- ){
val=b[I];
update(a[i] 1,1,X,1);
for(I=1;我我)
printf(%d%c ,as[i],i==n?\ n : );
返回0;
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。