Buy Tickets

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

线段树单点更新

题意:场景为排队买票,按照输入,可以插队,问最后的队列的顺序是怎么样的

解析:以序号构造线段树,以左子树来记录,然后查询并更新相应位置的编号(第二个数值);

// Buy Tickets.cpp : 定义控制台应用程序的入口点。
//

//#include "stdafx.h"
#include<cstdio>
#include<iostream>

using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1

const int maxn = 200005;
int sum[ maxn << 2 ], result[ maxn << 2 ];

struct node{
	int first, second;
}edge[ maxn << 2 ];
void PushUp( int rt ){
	sum[ rt ] = sum[ rt << 1 ] + sum[ rt << 1 | 1 ];
}

void Build( int l, int r, int rt ){
	if( l == r ){
		sum[ rt ] = 1;
		return;
	}
	int m = ( l + r ) >> 1;
	Build( lson );
	Build( rson );
	PushUp( rt );
}

void Update( int P, int Add, int l, int r, int rt ){
	if( l == r ){
		sum[ rt ] = 0;
		result[ l ] = Add;
		return;
	}
	int m = ( l + r ) >> 1;
	if( P < sum[ rt << 1 ] ){
		Update( P, Add, lson );
	}
	else{
		Update( P - sum[ rt << 1 ], Add, rson );
	}
	PushUp( rt );
}
//int _tmain(int argc, _TCHAR* argv[])
int main()
{
	int n;
	while( scanf( "%d", &n ) != EOF ){
		Build( 1, n, 1 );
		for( int i = 1; i <= n; ++i ){
			//cin >> edge[ i ].first >> edge[ i ].second;
			scanf( "%d%d", &edge[ i ].first, &edge[ i ].second );
		}
		for( int i = n; i >= 1; --i ){
			Update( edge[ i ].first, edge[ i ].second, 1, n, 1 );
		}
		for( int i = 1; i <= n; ++i ){
			printf( "%d%c", result[ i ], ( i == n )?'\n':' ' );
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值