算法提高之谜一样的牛
-
核心思想:树状数组
- 初始化树状数组为1 表示所有高度都没有用过
- 从后往前遍历h数组 分析身高
- 取当前h,即前面有h个比它高的 所以它是第h+1个数
- 求当前身高中 第h+1个数
- 用二分mid求sum找到第k个数
- 当前身高用过之后减1
cpp
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n;
int h[N];
int ans[N];
int tr[N];
int lowbit(int x)
{
return x&-x;
}
int sum(int x)
{
int res=0;
for(int i=x;i;i-=lowbit(i)) res += tr[i];
return res;
}
void add(int x,int c)
{
for(int i=x;i<=n;i+=lowbit(i)) tr[i] += c;
}
int main()
{
cin>>n;
for(int i=2;i<=n;i++) cin>>h[i];
for(int i=1;i<=n;i++) add(i,1); //每个位置+1
for(int i=n;i;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;
}
ans[i] = r; //r为第k个身高
add(r,-1);
}
for(int i=1;i<=n;i++) cout<<ans[i]<<endl;
}