Let’s look at the sample in the question first. For the given data, we can push from the back to the front. At the beginning, the cow’s height set {1, 2, 3, 4, 5} (each height can only be used once). The given data of 5 cows is 0, which means that there is no cow in front of it, and its height is 1. The remaining set {2,3,4,5}, for the fourth cow, the given data is 1. It means that there is only 1 cow shorter than it in the remaining set, which is the second smallest, indicating that its height is 3, and so on, we can calculate the height of each cow, so we can find that,For each cow ai, we only need to find a number ranked ai+1 in the remaining set, which is the height of the cow
Then our current problem is transformed into two problems: find the k-th smallest number from the remaining numbers and delete a certain number, so that we can use many methods, such as balanced trees, but it is more troublesome, we still use Do it with a tree array. To continue the transformation, we use the array subscript to represent each height, initialized to 1, which means that each height can only be used once, so deleting a certain number will become add(x, -1). For operation 1, we can use dichotomy
Because our sum seeks the prefix sum, then it must be an increasing sequence,Finding the k-th smallest number from the remaining numbers is equivalent to finding a smallest x in two, so that sum(x)=k (because the sequence is initialized with 1, the deletion becomes 0, so the value of the prefix sum Is the current ranking)
Code
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>usingnamespace std;constint N =1e5+10;int n;int h[N];int tr[N];int res[N];intlowbit(int x){
return x &-x;}voidadd(int x,int c){
for(int i = x; i <= n; i +=lowbit(i)){
tr[i]+= c;}}intsum(int x){
int res =0;for(int i = x; i; i -=lowbit(i)){
res += tr[i];}return res;}intmain(){
cin >> n;for(int i =2; i <= n; i++)scanf("%d",&h[i]);//初始化每个区间都为1(优化:每个区间的值其实就是长度)for(int i =1; i <= n; i++) tr[i]=lowbit(i);for(int i = n; i >=1; i--){
int k = h[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;}
res[i]= l;add(l,-1);}for(int i =1; i <= n; i++) cout << res[i]<< endl;return0;}