思路:
发现a[n]定下来以后,
第n位一定是a[n] +1
往前推
第n-1位就是 数1到n中 删掉了第a[n]+1大的数后
剩下的n-1个数中第a[n-1]+1大的数
以此类推
考虑如何在每次操作中快速找出第k大的数
因为数据只有8000,
可以考虑用桶记录是否选过数。
时间复杂度:O(
n
2
n^2
n2)
当然,因为是全排列,所以数的大小在1到n之间,
可以考虑差分后用树状数组维护去前缀和,通过二分答案来寻找
时间复杂度:O(
n
log
2
2
n
n \log_2^2n
nlog22n)
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 8e3 + 10;
int n, a[N], F[N];
bool f[N];
int find(int x)
{
int cnt = x + 1;
for(int i = n; i >= 1; i--)
{
if(!f[i])
{
if(!cnt) return f[i] = 1, i;
cnt--;
if(!cnt) return f[i] = 1, i;
}
}
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = n; i >= 1; i--) F[i] = find(a[i]);
for(int i = 1; i <= n; i++) printf("%d ", F[i]);
return 0;
}