题意: 有N 个人站队,告诉每个人想插队的位置,要求确定最终的站队位置。
分析: 越往后插队的人位置越固定,因此可以从后向前插入,每个人插入的位置为从第1 个位置起的第 pos+1 空位置。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define havemid int m=(l+r)>>1
#define left (rt<<1)
#define right (rt<<1|1)
#define clr(x) memset(x,0,sizeof(x))
const int maxn=200100;
struct p{
int pos,val;
}P[maxn];
int sum[maxn<<2];
int val[maxn<<2];
void pushup(int rt){
sum[rt]=sum[left]+sum[right];
}
void build(int l,int r,int rt){
if(l==r){
sum[rt]=1;
return ;
}
havemid;
build(lson);
build(rson);
pushup(rt);
}
void update(int pos,int l,int r,int rt,int va){
if(l==r){
val[l]=va;
sum[rt]=0;
return ;
}
havemid;
if(sum[left]>=pos)update(pos,lson,va);
else update(pos-sum[left],rson,va);
pushup(rt);
}
int main(){
int n,i;
while(scanf("%d",&n)!=EOF){
for(i=0;i<n;i++){
scanf("%d%d",&P[i].pos,&P[i].val);
}
build(1,n,1);
for(i=n-1;i>=0;i--){
update(P[i].pos+1,1,n,1,P[i].val);
}
for(i=1;i<=n;i++)
printf("%d ",val[i]);
printf("\n");
}
return 0;
}
本文介绍了一种通过从后向前插入的方式解决N个人排队问题的算法实现。该算法使用了树状数组来高效更新和查询队列中每个位置的人数。

被折叠的 条评论
为什么被折叠?



