POJ2828 思维难度较好的一道线段树

来源:互联网 发布:淘宝怎么查自己的排名 编辑:程序博客网 时间:2024/05/16 12:46

题目大意:一条队伍 ,给你每个人插队的状态,得到最后的队伍状态

思路:容易从后方去思考,首先最后一个百分之百可以确定的 而倒数第二个  倒着来看 他之前必定还有pos[i]个人 (未包括后面的人)所以能需要空pos[i]个人的位置就是倒数第二个人的位置,同理可得倒数第三 倒数第四,而线段树就去维护空位的信息

#include<stdio.h>#define maxn 200005#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int empty[maxn<<2];int A[maxn],B[maxn],C[maxn];int Pushup(int rt){    empty[rt]=empty[rt<<1]+empty[rt<<1|1];}int build(int l,int r,int rt){    if(l==r) {empty[rt]=1;return 0;}    int m=(l+r)>>1;    build(lson);    build(rson);    Pushup(rt);}int query(int x,int l,int r,int rt){    int temp,m;    m=(l+r)>>1;    if(l==r) {empty[rt]--;return l;}    if(x<=empty[rt<<1])        temp=query(x,lson);    else x=x-empty[rt<<1],temp=query(x,rson);    Pushup(rt);    return temp;}int main(){    freopen("poj2828.in","r",stdin);    freopen("poj2828.out","w",stdout);    int N,i;    while(~scanf("%d",&N))        {            build(1,N,1);            for(i=1;i<=N;i++)                scanf("%d%d",&A[i],&B[i]);            for(i=N;i>=1;i--)                C[query(A[i]+1,1,N,1)]=B[i];            for(i=1;i<=N;i++)                printf("%d ",C[i]);            printf("\n");        }    return 0;}