D. Restore Permutation

D. Restore Permutation

就是给一个n个数的全排,然后bi记录比ai小且在排在ai前面的数的和,求ai
树状数组维护,二分
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define si signed
#define endl '
'
#define sc(x) scanf("%I64d",&x);
#define read(A) for(int i=1;i<=n;i++)scanf("%I64d",&A[i]);
#define P pair<int,int>
#define fi first
#define se second
#define ot(x) cout<<x<<'
';
#define maxn 200000+500
int A[maxn];
int n,t,x,y,a,b;
int c[maxn];
int ans[maxn];
bool B[maxn];
int lowbit(int x)
{
    return x&(-x);
}
 
void add(int i,int k)
{
    while(i <= n+100)
    {
        c[i] += k;
        i += lowbit(i);
    }
}
 
int get(int i)
{
 
    int res = 0;
    while(i > 0)
    {
        res += c[i];
        i -= lowbit(i);
    }
    return res;
}
int solve(int x)
{
 
    int l=1,r=n;
    int mid;
    while(l+1<r)
    {
        mid=(l+r)/2;
        if(get(mid-1)<=x){
            l=mid;
        }else if(get(mid-1)>x){
            r=mid-1;
        }
    }
    int ans;
    if(get(r-1)==x){
        ans=r;
    }else ans=l;
 
    return ans;
}
signed main()
{
    sc(n);
 
    for(int i=1;i<=n;i++){
       sc(A[i]);
       add(i,i);
    }
    //
    int _j=1;
 
    for(int i=n; i>0; i--)
    {
        if(A[i]==0)
        {
            for(_j; _j<=n; _j++)
            {
                if(!B[_j])
                {
                    ans[i]=_j;
                    add(_j,-_j);
                    B[_j]=1;
                    break;
                }
            }
        }
        else
        {
            ans[i]=solve(A[i]);
            B[ans[i]]=1;
            // cout<<ans[i]<<'
';
            add(ans[i],-ans[i]);
        }
    }
    for(int i=1; i<=n; i++)
    {
        cout<<ans[i]<<' ';
    }
 
}
原文地址:https://www.cnblogs.com/liulex/p/11411165.html