hdu5592
代码:
//从后向前求,a[i]-a[i-1]+1表示当前剩余数中该数位于第几大
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<vector>
#include<stack>
using namespace std;
const int maxn=50005;
struct node{
int l,r;
int num;//num是每个区间当前待求结果的个数
int val;//表示所要找的的值的大小
}tree[maxn<<4];
int a[maxn],ans[maxn];
int n;
void build(int m,int l,int r)
{
tree[m].l=l;
tree[m].r=r;
tree[m].num=r-l+1;
if(l==r){
tree[m].val=l;
return ;
}
int mid=(l+r)>>1;
build(m<<1,l,mid);
build(m<<1|1,mid+1,r);
}
int query(int m,int k)
{
if(tree[m].l==tree[m].r){
return tree[m].val;
}
if(tree[m<<1].num>=k)
return query(m<<1,k);
else
return query(m<<1|1,k-tree[m<<1].num);
}
void update(int m,int x)//及时更改线段树里的num值,因为一些值已经求出来了,要剔除这些没用的值
{
tree[m].num--;
if(tree[m].l==tree[m].r){
return ;
}
if(tree[m<<1].r>=x)
update(m<<1,x);
else
update(m<<1|1,x);
return ;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(a,0,sizeof(a));
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
build(1,1,n);
for(int i=n;i>=1;i--){
ans[i]=query(1,i-(a[i]-a[i-1]));//求得时候要转化一下,query是从小到大查询,参数应该写该数的大小位次号
update(1,ans[i]);
}
for(int i=1;i<=n;i++){
if(i<n){
printf("%d ",ans[i]);
}
else{
printf("%d\n",ans[i]);
}
}
}
return 0;
}