POJ2828 Buy Tickets (线段树)

来源:互联网 发布:linux rm删除指定文件 编辑:程序博客网 时间:2024/06/05 00:26
题意 : 人们一个一个的来排队并插队,按人到来的顺序给出每个人插队的位置(插在第几个人后面),并告知每个人的id号,输出最终队伍的情况

分析 :这题我开始想了很久,怎么也没办法将题目和线段树联系在一起,看了网上的代码才发现,还真是线段树,而且还是很基础的那种......主要思想就是线段树记录空位,然后倒序插入,每个人插队的位置pos即为插入线段树时插入位置前的空位数......



#include  <cstdio>#define lson rt*2,left,mid#define rson rt*2+1,mid+1,rightusing namespace std;int SUM[1000000];int ans[300000];int pos[200000],val[300000];int startpos;int Max(int a,int b){return a>b?a:b;}void update(int rt){SUM[rt]=SUM[rt*2]+SUM[rt*2+1];}void build(int rt ,int left, int right){if (left==right){SUM[rt]=1;return ;}int mid=(left+right)/2;build(lson);build (rson);update(rt);}int query(int rt , int left ,int right ,int len){if (left==right){SUM[rt]=0;return left;}int mid=(left+right)/2;int ret;if (SUM[rt*2]>len)ret=query(lson,len);else ret=query(rson,len-SUM[rt*2]);update(rt);return ret;}int main(){int N;while (scanf("%d",&N)!=EOF){build(1,1,N);for (int i=0;i<N;i++){scanf("%d%d",&pos[i],&val[i]);}for (int i=N-1;i>=0;i--){ans[query(1,1,N,pos[i])]=val[i];}for (int i=1;i<=N;i++){printf("%d",ans[i]);if (i!=N)putchar(' ');else putchar('\n');}}return 0;}

0 0
原创粉丝点击