[线段树]poj 2182

题意: 

       n头牛站队,每头牛都有一个属于[1,n]唯一的数字。对于每头牛,现在已知前面多少头牛的数字比他的大,问这n头牛的数字序列。

思路:

      和poj2828很相似,都是从后向前计算,建立一颗线段树,节点val值为,这个区间的空位数,然后从后向前更新线段树,也就是说,如果一个节点无法插入当前位置,那么就选择右侧最靠近这个节点的位置

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int nMax = 8010;
struct{
    int l , r ,num;
}node[nMax*3];

int num[nMax] ,ans ,res[nMax];
void build(int l ,int r, int u){
    node[u].l = l;
    node[u].r = r;
    node[u].num = r - l + 1;
    if(l == r){
        return;
    }
    int m = (r + l)>>1;
    build(l , m , u*2);
    build(m + 1, r , u*2 + 1);
}

void update(int p ,int u){
    int l = node[u].l;
    int r = node[u].r;
    node[u].num -= 1;
    if(l == r){
        ans = r;
        return;
    }
    if(node[2*u].num >= p){
        update(p ,u*2);
    }else{
        p -= node[2*u].num;
        update(p ,u * 2 + 1);
    }
}
int main(){
    int n , i;
    while(scanf("%d",&n)!=EOF){
        for(i = 2 ;i <= n ;i++){
            scanf("%d",&num[i]);
            num[i] ++;
        }num[1] = 1;
        build(1 ,n ,1);
        for( i = n ; i >= 1; i--){
            update(num[i] ,1);
            res[i] = ans;
        }
        for(i = 1; i<= n; i++)
            printf("%d\n",res[i]);
    }
    return 0;
}

  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值