逆序数还原

 Problem Description

有一段时间Eric对逆序数充满了兴趣,于是他开始求解许多数列的逆序数(对于由1...n构成的一种排列数组a,逆序数即为满足i<j,ai>aj的数字对数),但是某天他发现自己遗失了原来的数列,只留下之前计算过程中留下的各个数字对应的逆序数,现在请你帮他还原出原序列。

 Input

数据有多组,请处理到文件结尾。

每组数据第一行为一个整数N(1<=N<=1000),表示该序列的数字个数。

第二行为N个整数,第i个数字表示排在ai之后比ai小的数字个数。

 Output

输出为一行N个整数,表示原数列。

 Sample Input

5 2 0 1 0 0

 Sample Output

3 1 4 2 5

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int c[1001],a[1200];
int n;
int low(int x)
{
return x&(-x);
}
int sum(int x)
{
int cnt=0;
while(x>0)
{
cnt+=c[x];
x-=low(x);
}
return cnt;
}
void add(int x,int num)
{
while(x<=n)
{
c[x]+=num;
x+=low(x);
}
}
int main()
{
int num;
while(scanf("%d",&n)!=EOF)
{
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
add(i,1);
for(int i=1;i<=n;i++)
{
scanf("%d",&num);
num++;
for(int j=1;j<=n;j++)
if(sum(j)==num)
{
a[i]=j;
add(j,-1);
break;
}
}
for(int i=1;i<=n;i++)
{
if(i!=1)
printf(" ");
printf("%d",a[i]);
}
printf(" ");
}
return 0;
}

题目分析

用树状数组解决,只要想明白就行

原文地址:https://www.cnblogs.com/tsw123/p/4361306.html