题意:排队买票,但是 中途 出现插队情况,比如 0 123,代表值为123的人 插入到 0 的位置,如果后面 出现 0 456,那么新的 0的位置就是 456,123就变成是 1的位置了
分析:这道题应该从后往前插入,当要插的位置小于左边的空位数时,就往左边插,否则往右边插,并且此刻插的位置要减去左边的空位数
#include<cstdio> #include<iostream> #define lson l,m,now*2 #define rson m+1,r,now*2+1 #define M 200010 using namespace std; int sum[M*4],ans[M]; struct node { int pos,zh; };node per[M]; void push_up(int now) { sum[now]=sum[now*2]+sum[now*2+1]; } void build(int l,int r,int now) { if(l==r) { sum[now]=1; return; } int m=(l+r)/2; build(lson); build(rson); push_up(now); } void change(int p,int v,int l,int r,int now) { if(l==r) { ans[l]=v; sum[now]=0; return; } int m=(l+r)/2; if(p<sum[now*2]) change(p,v,lson); else change(p-sum[now*2],v,rson); push_up(now); } int main() { int n; while(~scanf("%d",&n)) { build(0,n-1,1); for(int i=0;i<n;i++) scanf("%d%d",&per[i].pos,&per[i].zh); for(int i=n-1;i>=0;i--) change(per[i].pos,per[i].zh,0,n-1,1); for(int i=0;i<n;i++) printf("%d ",ans[i]); printf("\n"); } return 0; }
时间: 2024-10-09 15:21:04