bestcoder#65ZYB's Premutation 树状数组+二分

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 50010 ;
int tree[maxn] ;
int n ;
int getsum(int x){
    int sum = 0 ;
    while(x){
       sum += tree[x] ;
       x -= x&(-x) ;
    }
    return sum ;
}
void update(int x , int dx){
    while(x <= n){
        tree[x] += dx ;
        x += x&(-x) ;
    }
}
int find(int x , int ss){
    int l = 1 ;
    int r = n ;
    while(l <= r){
        int mid = (l + r) >> 1;
        int sum = ss-(mid-getsum(mid)) ;
        if(sum > x){
           l=mid+1;
        }
        else if(sum <= x){
            r=mid-1 ;
        }
    }
    return r+1 ;
}
int a[maxn] ;
int ans[maxn] ;
int main()
{
   int t ;
   scanf("%d" , &t) ;
   while(t--){
       scanf("%d" , &n) ;
       for(int i = 1;i <= n;i++){
          scanf("%d" , &a[i]) ;
          tree[i] = 0 ;
       }
       for(int i = n;i >= 1;i--){
           int sum = a[i] - a[i-1] ;
           ans[i] = find(sum , i) ;
           update(ans[i] , 1) ;
       }
       for(int i = 1;i <= n;i++){
           printf("%d%c" , ans[i] , i == n ?'\n':' ') ;
       }
   }
   return  0;
}

你可能感兴趣的:(bestcoder#65ZYB's Premutation 树状数组+二分)