问题描述
ZYBZYBZYB有一个排列PPP,但他只记得PPP中每个前缀区间的逆序对数,现在他要求你还原这个排列. (i,j)(i<j)(i,j)(i < j)(i,j)(i<j)被称为一对逆序对当且仅当Ai>AjA_i>A_jAi>Aj
输入描述
第一行一个整数TTT表示数据组数。 接下来每组数据: 第一行一个正整数NNN,描述排列的长度. 第二行NNN个正整数AiA_iAi,描述前缀区间[1,i][1,i][1,i]的逆序对数. 数据保证合法. 1≤T≤51 leq T leq 51≤T≤5,1≤N≤500001 leq N leq 500001≤N≤50000
输出描述
TTT行每行NNN个整数表示答案的排列.
输入样例
1 3 0 1 2
输出样例
3 1 2
超时:::
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
int main ()
{
int T,n;
scanf("%d",&T);
long long int arr[50010];
int mark[50010],cnt;
int res[50010];
bool vis[50010];
for(int xx=0; xx<T; xx++)
{
memset(vis,0,sizeof(vis));
cnt = 0;
int n;
long long temp;
scanf("%d",&n);
if(n>=1)
scanf("%I64d",arr);
long long int xxx=0;
for(int i=1; i<n; i++){
scanf("%I64d",&temp);
arr[i] = temp-xxx,xxx=temp;
}
for(int i=0; i<n; i++)
{
for(int i=n-1; i>=0; i--)
{
if(arr[i]==0&&!vis[i])
{
mark[cnt++] = i;
arr[i]--;
vis[i]=1;
break;
}
else arr[i]--;
}
}
int mmax = n;
for(int i=0; i<n; i++,mmax--)
res[mark[i]] = mmax;
for(int i=0; i<n; i++){
if(i!=n-1) printf("%d ",res[i]);
else printf("%d",res[i]);
}
printf("
");
}
return 0;
}