POJ 2828 Buy Tickets 線段樹

來源:互聯網
上載者:User

題意:買火車票時總有人插隊,每人有兩個屬性,插入位置pos[i] (pos[i]代表此人前面的總人數),以及人物編號 value[i]。在每一輪輸入後,按隊伍順序輸出人物的編號。
題解:處理點的線段樹。從後往前推,則可以避免後來人對pos的影響,這樣一來每個人的pos都是精確的。 

#include <iostream>using namespace std;#define MAX 200005int pos[MAX], value[MAX], out[MAX];struct item{int left, right, person;/*person代表當前節點區間可容納的人數*/} node[MAX*3];void build_tree ( int l, int r, int root ){node[root].left = l;node[root].right = r;node[root].person = r - l + 1;if ( l == r ) return;int mid = ( l + r ) / 2;build_tree ( l, mid, root * 2 );build_tree ( mid + 1, r, root * 2 + 1 );}int update ( int p, int root ){node[root].person --; /*每插入一個人,則節點區間的容量減小1*/if ( node[root].left == node[root].right ) /*當左右座標相等時,已經確定到點,即插入者得位置確定*/return node[root].left;int lchild = root * 2;int rchild = root * 2 + 1;if ( node[lchild].person >= p ) /*r若左子樹的容量大於插入者的位置,那麼插入者的最終位置一定在左子樹的區間內*/return update( p, lchild );else{p -= node[lchild].person; /* 假設某人的需要給前面的人留5個空位,左子樹可以提供3個,那麼就還需右子樹提供2個*/return update ( p, rchild );}}int main(){int n, index, i;while ( scanf("%d",&n) != EOF ){build_tree( 1, n, 1 );for ( i = 1; i <= n; ++i )scanf("%d%d", &pos[i], &value[i]);for ( i = n; i >= 1; --i ){index = update ( pos[i]+1, 1 );out[index] = value[i];}for ( i = 1; i <= n; ++i )printf("%d ",out[i]);putchar('\n');}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.