问题描述
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; }