POJ 2828 Buy Tickets

来源:互联网 发布:苹果7移动网络连接不上 编辑:程序博客网 时间:2024/04/29 02:28

题目大意:

把一群人插进一个队列,求所有操作结束后的队列。


解题思路:

这个题非常好,反着来想这个题,从最后一个人倒序插入,逆推出得到我们希望的答案。

线段树维护,当前位置(区间)内有多少个空位。


线段树重要的不在于线段树本身,而在于它维护的是什么。


#include<cstdio>#include<cstring>#include<cmath>#define maxn 200005using namespace std;int spr[maxn<<2],q[maxn];int max(int x,int y){if (x>y) return x;else return y;}int min(int x,int y){if (x<y) return x;else return y;}void PushUP(int rt){spr[rt]=spr[rt<<1]+spr[rt<<1|1];}void build(int l,int r,int rt){if (l==r) {spr[rt]=1;return;}int mid=(l+r)>>1;build(l,mid,rt<<1);build(mid+1,r,rt<<1|1);PushUP(rt);}void update(int p,int v,int l,int r,int rt){if (l==r) {q[l]=v;spr[rt]=0;return ;}int mid=(l+r)>>1;if (spr[rt<<1]>=p) update(p,v,l,mid,rt<<1);else update(p-spr[rt<<1],v,mid+1,r,rt<<1|1);PushUP(rt);}int main(){int n,p[maxn],v[maxn];while (scanf("%d",&n)!=EOF) {build(1,n,1);for (int i=1;i<=n;i++)scanf("%d%d",&p[i],&v[i]);for (int i=n;i>0;i--)update(p[i]+1,v[i],1,n,1);for (int i=1;i<=n;i++)printf("%d ",q[i]);printf("\n");}return 0;}


0 0
原创粉丝点击