题目链接
Problem Description
ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutation,now he ask you to
restore the premutation.
Pair (i,j)(i<j) is considered as a reverse log if Ai>Aj is matched.
Input
In the first line there is the number of testcases T.
For each teatcase:
In the first line there is one number N.
In the next line there are N numbers Ai,describe the number of the reverse logs of each prefix,
The input is correct.
1≤T≤5,1≤N≤50000
Output
For each testcase,print the ans.
Sample Input
1
3
0 1 2
Sample Output
3 1 2
Source
BestCoder Round #65
题意:给定一个数组a,a【i】代表原数组中【1,i】的逆序数的个数,要求你还原原数组。
思路:从后往前遍历,再自己后面的数都知道以及前面逆序数的个数时就可以确定第i个数,比如a【i】等于3,n=10,后面的数是5,6,7。那么剩余的数组就是1 2 3 4 8 9 10,又因为a【i】等于3,所以原数组第i个数就是4。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+1;
#define lowbit(i) (i)&(-i)
int n,c[maxn],a[maxn],ans[maxn];
void update(int x,int v)
{
while(x<maxn) c[x]+=v,x+=lowbit(x);
}
ll query(int x)
{
ll res=0;
while(x>0) res+=c[x],x-=lowbit(x);
return res;
}
int check(int x)
{
int l=1,r=n;
while(l<=r)
{
int mid=(l+r)>>1,t=query(n)-query(mid);
if(t<=x) r=mid-1;
else l=mid+1;
}
return l;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<maxn;++i) c[i]=0;
for(int i=1;i<=n;++i) scanf("%d",&a[i]),update(i,1);
a[0]=0;
ans[n]=n-(a[n]-a[n-1]);update(ans[n],-1);
for(int i=n-1;i>=1;--i)
{
ans[i]=check(a[i]-a[i-1]);
update(ans[i],-1);
}
for(int i=1;i<=n;++i) printf("%d%s",ans[i],(i==n)?"\n":" ");
}
}