题目:Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue…
The Lunar New Year was approaching, but unluckily the Little Cat still had schedules going here and there. Now, he had to travel by train to Mianyang, Sichuan Province for the winter camp selection of the national team of Olympiad in Informatics.
It was one o’clock a.m. and dark outside. Chill wind from the northwest did not scare off the people in the queue. The cold night gave the Little Cat a shiver. Why not find a problem to think about? That was none the less better than freezing to death!
People kept jumping the queue. Since it was too dark around, such moves would not be discovered even by the people adjacent to the queue-jumpers. “If every person in the queue is assigned an integral value and all the information about those who have jumped the queue and where they stand after queue-jumping is given, can I find out the final order of people in the queue?” Thought the Little Cat.
大意:有n个人,每个人都被分配了可以插到第i个人的后面和一个数值,问经过n次插队后,最终按照队列顺序输出他们各自的数值。
思路:(感觉这题有点像前面的lost cow),如果从前往后遍历,那么前面的有可能被后面的人插队,所以我们先从后面往前推,因为这样有人的位置就固定了,不会改变。tr[u].sum代表tr[u].l到tr[u].r这个区间总共的座位。每次更新一下,如果那个位置小于它所要插进去的地方,那么就往右遍历,反之往左,最后pushup更新一下即可。
代码:
#include<algorithm>
#include<iostream>
using namespace std;
const int N=2e5+5;
struct node{int l,r;int sum;
}tr[N<<2];
int pos[N],val[N],ans[N];
void pushup(int u)
{tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void bt(int u,int l,int r)
{if(l==r){tr[u].l=tr[u].r=l;tr[u].sum=1;//初始化都为没人}else{int mid=l+r >> 1;bt(u<<1,l,mid);bt(u<<1|1,mid+1,r);pushup(u);}
}
void update(int u,int l,int r,int p,int v)
{if(l==r){ans[l]=v;tr[u].sum=0;//表示已经有人}else{int mid=l+r>>1;if(p<tr[u<<1].sum) update(u<<1,l,mid,p,v);//小于左边的空位置总和,说明可以左边可以插队else{update(u<<1|1,mid+1,r,p-tr[u<<1].sum,v);//往右遍历的时候需要减去左边的空位置}pushup(u);}
}
int main()
{int n;while(scanf("%d",&n)!=EOF){bt(1,1,n);for(int i=0;i<n;i++){scanf("%d %d",&pos[i],&val[i]);}for(int i=n-1;i>=0;i--){update(1,1,n,pos[i],val[i]);}for(int i=1;i<n;i++){printf("%d ",ans[i]);}printf("%d\n",ans[n]);}
}