码迷,mamicode.com
首页 > 其他好文 > 详细

●POJ 2828 Buy Tickets

时间:2018-01-27 15:22:51      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:get   void   while   targe   log   max   blog   font   style   

题链:

http://poj.org/problem?id=2828

题解:

线段树。

逆向考虑这个过程。最后的序列S共有n个元素。

先看最后一个人,如果他插入到第i位,那么他最终的位置就是当前序列S的第i号位置,然后把这个位置去掉,得到新序列S‘。

再按上面的操作确定倒数第二个人的位置:

如果他插入到第j位,那么他就在新序列S‘的第j个位置。

。。。。。。以此类推,可以确定出所有人的位置。

可以用线段树去确定位置。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 200050
using namespace std;
struct People{
	int p,d;
}P[MAXN];
struct SGT{
	int ls[MAXN<<1],rs[MAXN<<1],siz[MAXN<<1],sz,rt;
	void build(int &u,int l,int r){
		u=++sz; siz[u]=r-l+1;
		if(l==r) return;
		int mid=(l+r)/2;
		build(ls[u],l,mid);
		build(rs[u],mid+1,r);
	}
	void Reset(int n){
		sz=rt=0;
		build(rt,1,n);
	}
	int Modify(int u,int l,int r,int k){
		siz[u]--; if(l==r) return l;
		int mid=(l+r)/2;
		if(k<=siz[ls[u]]) return Modify(ls[u],l,mid,k);
		else return Modify(rs[u],mid+1,r,k-siz[ls[u]]);
	}
}DT;
int ANS[MAXN];
int main(){
	int n;
	while(~scanf("%d",&n)){
		DT.Reset(n);
		for(int i=1;i<=n;i++) scanf("%d%d",&P[i].p,&P[i].d);
		for(int i=n,p;i;i--){
			p=DT.Modify(DT.rt,1,n,P[i].p+1);
			ANS[p]=P[i].d;
		}
		for(int i=1;i<n;i++) printf("%d ",ANS[i]);
		if(n) printf("%d\n",ANS[n]);
	}
	return 0;
}

  

●POJ 2828 Buy Tickets

标签:get   void   while   targe   log   max   blog   font   style   

原文地址:https://www.cnblogs.com/zj75211/p/8365585.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!