题意
传送门 POJ 2182
题解
已知每个位置的左侧 b r a n d brand brand 值小于该位置的牛 b r a n d brand brand 值的牛的数量,那么从后向前考虑,可以直接判断最右侧位置牛的 b r a n d brand brand 值。
B I T BIT BIT 维护牛的 b r a n d brand brand 值在当前未知的左侧队列中的序号,每次从高位向低位枚举比特 O ( l o g N ) O(logN) O(logN) 求解序号为 i i i 的牛的 b r a n d brand brand 值,然后将其删除。总的复杂度 O ( N × l o g N ) O(N\times logN) O(N×logN)。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 8005
int N, num[maxn], bit[maxn], res[maxn];
void add(int i, int x)
{
while (i <= N)
{
bit[i] += x;
i += i & -i;
}
}
int seeksum(int x)
{
int res = 0, sum = 0;
for (int i = 13; i >= 0; i--)
{
res += 1 << i;
if (res > N || sum + bit[res] >= x)
{
res -= 1 << i;
}
else
{
sum += bit[res];
}
}
return res + 1;
}
int main()
{
scanf("%d", &N);
for (int i = 2; i <= N; i++)
{
scanf("%d", num + i);
}
for (int i = 1; i <= N; i++)
{
add(i, 1);
}
for (int i = N; i; i--)
{
res[i] = seeksum(num[i] + 1);
add(res[i], -1);
}
for (int i = 1; i <= N; i++)
{
printf("%d\n", res[i]);
}
return 0;
}