poj 2828

排队买票,但是 中途 出现插队情况,比如 0 123,代表值为123的人 插入到 0 的位置,如果后面 出现 0 456,那么新的 0的位置就是 456,123就变成是 1的位置了

观察发现,最后一个插入到该位置的人位置是固定的,那么我们可以从后面进行插入操作,pos val 代表val要插入到pos位置,那么就是说 pos 前面要留出 pos个位置,

因为 是从 0 开始的。

线段树 :res 记录 该区间 目前还剩 res个空位,每一次 query即插入的时候 ,如果 该节点左儿子 res >=pos,那么只要在左儿子找就可以了

否则 要在右儿子中 找 ,此时 pos 改为 pos-左儿子res。。

#include<iostream>
#include<algorithm>
using namespace std;

#define MAXN 200005
#define lson u<<1
#define rson u<<1|1

struct In{
	int p,v;
}dat[MAXN];

int ans[MAXN];

struct Node{
	int lef,rig;
	int res;//记录当前区间有多少空位
}T[MAXN<<2];

void Build(int u,int l,int r){
	T[u].lef=l;
	T[u].rig=r;
	if(l==r){T[u].res=1;return;}
	int mid=(l+r)>>1;
	Build(lson,l,mid);
	Build(rson,mid+1,r);
	T[u].res=T[lson].res+T[rson].res;
}

void Query(int u,int pos,int val){
	T[u].res--;
	if(T[u].lef==T[u].rig){
		ans[T[u].lef]=val;
	}
	else {
		if(pos<=T[lson].res)Query(lson,pos,val);
		else Query(rson,pos-T[lson].res,val);
	}

}

int main(){
	int N,i;
	while(scanf("%d",&N)==1){
		Build(1,1,N);
		//printf("u %d\n",T[1].res);
		for(i=1;i<=N;i++)scanf("%d%d",&dat[i].p,&dat[i].v);
		for(i=N;i>=1;i--)Query(1,dat[i].p+1,dat[i].v);	
		
		for(i=1;i<=N;i++){
			printf("%d%c",ans[i],i<N?' ':'\n');
		}
	}
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值