解题思路
首先要观察出这个身高是怎么排序怎么构造的,可以发现要从后往前开始分配,因为后一个牛的身高不影响前一个牛的位置,但是相反就不一样的;所以说每个牛的位置至于排在他前面的牛有关系,所以说每次处理完最后一个牛之后就要将这个牛删掉,以免他去影响其他的牛。
来看初始化,因为开始的最后一头牛,其他所有的牛都在而且都会影响它,那么这时候要假设所有牛都在,可以用1来表示当前这个牛是否存在,然后树状数组处理之后再求单点查询就是这个牛所在的位置;
但是在查询的时候要用到二分来简化搜索,每查完一次,都要将这个牛删掉!
Accepted
#include <iostream>
using namespace std;
const int N = 100010;
int a[N],n;
int t[N],ans[N];
int lowbit(int x) {
return x & -x;
}
void add(int x,int c) {
for(int i = x;i <= n;i+=lowbit(i)) t[i] += c;
}
int sum(int x) {
int res = 0;
for(int i = x;i ;i-= lowbit(i)) {
res += t[i];
}
return res;
}
int main() {
scanf("%d",&n);
for(int i = 2;i <= n;i++) scanf("%d",&a[i]);
// 初始化树状数组,因为是全为1 所以对应的树状数组就是区间的长度
for(int i = 1;i <= n;i++) t[i] = lowbit(i);
for(int i = n;i;i--) {
int k = a[i] + 1;
int l = 1,r = n;
while(l < r) {
int mid = l + r >> 1;
if(sum(mid) >= k) r = mid;
else l = mid + 1;
}
ans[i] = r;
add(r,-1); // 将这个位置的数删掉
}
for(int i = 1;i <= n;i++) printf("%d\n",ans[i]);
return 0;
}