丢失的牛

TimeLimit: 1 Second   MemoryLimit: 64 Megabyte

Totalsubmit: 1   Accepted: 1  

Description

FJ养了N(2 <= N <= 8000)头牛,每一头都有它自己的编号:1..N。
一天,牛们喝醉了,排队回家,但忘了如何按编号排队,它们唯一能知道的就是前面有多少牛的编号比自己的小,请年轻的ACMer帮FJ找出牛们确切排序。

Input

第一行为牛的个数N,之后N-1行,每行有一个数字,代表排在第2头到第N头牛前面编号比自己小的牛的数量。

Output

共N行,输出在排队中第一头到最后一头牛的编号,每个数占一行。

Sample Input


5
1
2
1
0

Sample Output


2
4
5
3
1


#include <iostream>

using namespace std;

#define MAXN 8001

int temp[MAXN], ans[MAXN];

struct Node
{
        int l, r, cnt;
};

class SGtree
{
        public:
        
        Node node[MAXN << 2];
        
        void Maketree(int i, int l, int r);
        
        void Update(int i, int val);
        
        int Query(int i, int k);
}tree;

void SGtree::Maketree(int i, int l, int r)
{
        node[i].l = l;
        node[i].r = r;
        int mid = (l + r) >> 1;
        
        if (l == r)
        {
                node[i].cnt = 1;
                return ;
        }
        
        Maketree(i * 2, l, mid);
        Maketree(i * 2 + 1, mid + 1, r);
        
        node[i].cnt = node[i * 2].cnt + node[i * 2 + 1].cnt;
}

void SGtree::Update(int i, int val)
{
        int l = node[i].l;
        int r = node[i].r;
        int mid = (l + r) >> 1;
        
        if (l == r)
        {
                node[i].cnt = 0;
                return ;
        }
        
        if (val <= mid)
        {
                Update(i * 2, val);
        }
        else
        {
                Update(i * 2 + 1, val);
        }
        
        node[i].cnt = node[i * 2].cnt + node[i * 2 + 1].cnt;
}

int SGtree::Query(int i, int k)
{
        int l = node[i].l;
        int r = node[i].r;
        int mid = (l + r) >> 1;
        
        if (l == r)
        {
                return l;
        }
        
        if (node[i * 2].cnt > k)
        {
                return Query(i * 2, k);
        }
        else
        {
                return Query(i * 2 + 1, k - node[i * 2].cnt);   
        }
}

void input()
{
        int n;
        
        cin >> n;
        
        for (int i = 1; i < n; i++)
        {
                scanf("%d", &temp[i]);
        }
        
        temp[0] = 0;
        
        tree.Maketree(1, 1, n);
        
        for (int i = n - 1; i >= 0; i--)
        {
                int flag = tree.Query(1, temp[i]);
                ans[i] = flag;
                tree.Update(1, flag);
        }
        
        for (int i = 0; i < n; i++)
        {
                printf("%d\n", ans[i]);
        }
}

int main()
{
        input();
        return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值