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;
}