Poj 2828 Buy Tickets

题目大意:有N个人排队,给出各个人想插队的位置和标识,要求输出最后的序列。

思路:利用线段树,从最后一个人往前插,这样position的意义就表示前面有多少个空位,线段树上每个节点中存储的是区间有多少空位。

#include <iostream>
using namespace std;
#include <stdio.h>
const int MAXN = 200010;
struct tree {
	int left;
	int right;
	int ctr;
};
struct tree T[4*MAXN];
int position[MAXN];
int value[MAXN];
int order[MAXN];

void initialize(int left, int right, int p) {
	T[p].left=left;
	T[p].right=right;
	T[p].ctr=right-left+1;

	if (left==right)
		return;

	int mid=(left+right)>>1;

	initialize(left,mid,2*p);
	initialize(mid+1,right,2*p+1);
}
void insert(int p, int v, int nodeNum) {
	T[nodeNum].ctr--;

	if (T[nodeNum].left==T[nodeNum].right) {
		order[T[nodeNum].left]=v;
		return;
	}
	if (T[2*nodeNum].ctr>=p)
		insert(p,v,2*nodeNum);
	else 
		insert(p-T[2*nodeNum].ctr,v,2*nodeNum+1);
}
int main()
{
	int n,i;

	while (scanf("%d",&n)!=EOF) {
		for (i=0;i<n;i++) {
			scanf("%d%d",&position[i],&value[i]);
			position[i]++;
		}
		initialize(1,n,1);
		for (i=n-1;i>=0;i--)
			insert(position[i],value[i],1);
		for (i=1;i<=n;i++)
			printf("%d%c",order[i],i==n?'\n':' ');
	}
	return 0;
}


你可能感兴趣的:(Poj 2828 Buy Tickets)