POJ 2828 Buy Tickets(线段树-单点更新)


点击打开链接

比较裸的线段树,主要在能不能想到(。ì _ í。)

/*
思路:
设当前节点为root,其左孩子为lchild,右孩子为rchild,节点的存放变量为val,待插入数值为value.
1、建立线段树。每个结点存放其所在范围的还能存放的数值的个数
2、更新线段树。
	(1、)root为线段树叶子结点。
	(2、)position(value)<=lchild.val,则更新左孩子;否则position(value)-=lchild.val,更新右孩子。

*/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>

using namespace std;

int pos[200010];
int val[200010];
int f[200010];
int index;
struct SegTreeNode
{
	int Val;//结点所在的范围内还能够存放几个数
}SegTree[200010<<2];
/*
作用:建立线段树
root:节点编号
[Begin, End]:结点表示的范围
*/
void creat(int root, int Begin, int End)
{
	if(Begin == End)
	{
		SegTree[root].Val = End-Begin+1;
		return ;
	}

	int mid = (Begin+End)>>1;
	creat(root<<1, Begin, mid);
	creat(root<<1|1, mid+1, End);

	SegTree[root].Val = SegTree[root<<1].Val+SegTree[root<<1|1].Val;
}
/*
作用:更新线段树
root:结点编号
[Begin, End]:结点表示的范围
pos:插入value的位置
*/
void Update(int root, int Begin, int End, int pos)
{
	SegTree[root].Val--;
	if(Begin == End)
	{
		index = Begin;
		return;
	}

	int mid = (Begin+End)>>1;
	if(pos<=SegTree[root<<1].Val)
	{
		Update(root<<1,Begin, mid, pos);
	}
	else
	{
		pos-=SegTree[root<<1].Val;
		Update(root<<1|1, mid+1, End, pos);
	}
}
int main()
{
	int n;

	while(~scanf("%d",&n))
	{
		creat(1,1,n);
		for(int i=1;i<=n;i++)
		{
			scanf("%d %d",&pos[i],&val[i]);
			pos[i]+=1;
		}

		for(int j=n;j>=1;j--)
		{
			Update(1,1,n,pos[j]);
			f[index] = val[j];
		}

		for(int i=1;i<=n;i++)
			printf(i!=n?"%d ":"%d\n",f[i]);
	}

	return 0;
}


发布了88 篇原创文章 · 获赞 7 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Q_smell/article/details/69659655