poj 3278,poj1208

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: