首页 > 代码库 > (中等) POJ 2828 Buy Tickets , 逆序+线段树。

(中等) POJ 2828 Buy Tickets , 逆序+线段树。

Description:

  Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue…

  The Lunar New Year was approaching, but unluckily the Little Cat still had schedules going here and there. Now, he had to travel by train to Mianyang, Sichuan Province for the winter camp selection of the national team of Olympiad in Informatics.

  It was one o’clock a.m. and dark outside. Chill wind from the northwest did not scare off the people in the queue. The cold night gave the Little Cat a shiver. Why not find a problem to think about? That was none the less better than freezing to death!

  People kept jumping the queue. Since it was too dark around, such moves would not be discovered even by the people adjacent to the queue-jumpers. “If every person in the queue is assigned an integral value and all the information about those who have jumped the queue and where they stand after queue-jumping is given, can I find out the final order of people in the queue?” Thought the Little Cat.

 

  就是说几个人在排队,有人插队,然后问最后的队列是啥样。

  很经典的问题(可是我没想出来。T T)。

  从后往前枚举,建树。 首先最后一个人在哪就是哪,那么他前面的人如果原来在的位置在最后一个人插入的位置之后,那么就要向后移一个位置。

  所以说就是到了某个人时(倒序枚举),假设他要插在3这个位置,那么第三个空的地方(已经有人的不计数)就是他的位置。

 

  代码如下:

#include<iostream>#include<cstdio>using namespace std;int BIT[200002*4];int N;int num[200002];int val[200002];int ans[200002];void build_tree(int L,int R,int po){    BIT[po]=R-L+1;    if(L==R) return;    int M=(L+R)/2;    build_tree(L,M,po*2);    build_tree(M+1,R,po*2+1);}int query_update(int qn,int L,int R,int po){    --BIT[po];    if(L==R) return L;    int M=(L+R)/2;    if(BIT[po*2]>=qn)        return query_update(qn,L,M,po*2);    else        return query_update(qn-BIT[po*2],M+1,R,po*2+1);}int main(){    int temp;    while(~scanf("%d",&N))    {        for(int i=N;i>=1;--i)            scanf("%d %d",&num[i],&val[i]);        build_tree(1,N,1);        for(int i=1;i<=N;++i)        {            temp=query_update(num[i]+1,1,N,1);            ans[temp]=val[i];        }        for(int i=1;i<=N;++i)            printf("%d ",ans[i]);        printf("\n");    }    return 0;}

 

(中等) POJ 2828 Buy Tickets , 逆序+线段树。