题意:给定数组每个数前面(包括这个数)的逆序对数量,求原数组的值
思路:
1.a[i]-a[i-1]可以得到该数的之前比它大的数的数量
2.从后往前遍历,只需要求出数组的第(a[i]-a[i-1]+1)大的数就是该位的值,
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=5e4+10;
int a[N];
int b[N];
int c[N];
int n;
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int a)
{
while(x<=n)
{
b[x]+=a;
x+=lowbit(x);
}
}
int ask(int x)
{
int ans=0;
while(x)
{
ans+=b[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(b,0,sizeof b);
for(int i=1;i<=n;i++)
{
add(i,1);
scanf("%d",&a[i]);
// a[i]=a[i]-a[i-1];如果这样写的话,a[i]就不是原来的含义了,a[i+1]就会求错
}
for(int i=n;i>=1;i--)
{
int l=1,r=n;
while(l<r)
{
int mid=(l+r)/2;
if(ask(mid)>=i-(a[i]-a[i-1])) r=mid;
else l=mid+1;
}
c[i]=l;
add(l,-1);
}
for(int i=1;i<=n;i++)
{
if(i==1) printf("%d",c[i]);
else printf(" %d",c[i]);
}
printf("\n");
}
}