Buy Tickets POJ - 2828

本文介绍了一种使用线段树数据结构来高效解决特定座位安排问题的方法。通过逆向思维,从最后一个人开始安排位置,利用线段树进行单点更新,实现了快速查找并确定每个人的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

逆向处理,初始有n个空位,我们先处理第n个人,显然第n个人的位置一定再第pos[n]+1个空位上,之后剩下了n-1个空位,再处理第n-1个人,同理他在第pos[n-1]+1个空位上,依此类推。那么我们要解决的问题就成了怎么快速的找到第k个空位,这个问题类似线段树的单点更新

segtree数组的容量原来设置的是2*MAXN,结果WA,后来看吴老师书后改为3*MAXN,然后AC了,200000个节点真的需要这么大的空间?

#include<iostream> 
#include<cstring> 
#include<cstdio>
#include<string> 
#include<iomanip> 
#include<limits>
#include<vector>
#include<algorithm> .
#pragma warning(disable:4996) 
using namespace std;
const int MAXN = 200100;
int p[MAXN], v[MAXN], segtree[MAXN * 3], ans[MAXN];
void build(int root, int nstart, int nend)
{
	if (nstart == nend) {
		segtree[root] = 1;
		return;
	}
	int mid = (nstart + nend) / 2;
	build(2 * root + 1, nstart, mid);
	build(2 * root + 2, mid + 1, nend);
	segtree[root] = segtree[2 * root + 1] + segtree[2 * root + 2];
}
int insert(int root, int nstart, int nend,int index)
{
	if (nstart == nend) {
		segtree[root]--;
		return nstart;
	}
	int mid = (nstart + nend) / 2, t;
	if (segtree[2 * root + 1] >= index) t= insert(2 * root + 1, nstart, mid, index);
	else t= insert(2 * root + 2, mid + 1, nend, index - segtree[2 * root + 1]);
	segtree[root] = segtree[2 * root + 1] + segtree[2 * root + 2];
	return t;
}
int main()
{
	int n, p[MAXN], v[MAXN];
	while (~scanf("%d", &n))
	{
		build(0, 0, n - 1);
		
		for (int i = 0; i < n; i++)
			scanf("%d%d", &p[i], &v[i]);
		for (int i = n - 1; i >= 0; i--) 
			ans[insert(0, 0, n - 1, p[i] + 1)] = i;
		for (int i = 0; i < n - 1; i++)
			printf("%d ", v[ans[i]]);
		printf("%d", v[ans[n - 1]]);
		puts("");	
	}

}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值