D. Restore Permutation(樹狀數組+二分)

D. Restore Permutation

題意:第一行給你一個數n,第二行輸入n個數,第 i 個數表示其前面的所有比其小的數的和,讓你還原這個原數列(該原數列數值1->n)。

思路:從後往前解決。利用樹狀數組求出tree[i]。利用二分查找a[i],確定位置,存入s[i],最後輸出。

代碼:

#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll tree[N],n;
ll a[N],s[N];
ll lowbit(ll k)
{
    return k&(-k);
}
void add(ll k,ll num)
{
    while(k<=n)
    {
        tree[k]+=num;
        k+=lowbit(k);
    }
}
ll read(ll k)
{
    ll sum=0;
    while(k)
    {
        sum+=tree[k];
        k-=lowbit(k);
    }
    return sum;
}
ll tao(ll x)
{
    ll ret=-1;
    ll l=1,r=n,mid;
    while(l<=r)
    {
        mid=(l+r)>>1;
        ll ans=read(mid-1);

        if(ans<=x)
        {
            l=mid+1;
            ret=mid;
        }
        else
            r=mid-1;
    }
    add(ret,-ret);
    return ret;
}
int main()
{
    scanf("%lld",&n);
    for(ll i=1;i<=n;i++)
    {
        add(i,i);
    }
    for(ll i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
    }
    for(int i=n;i>=1;i--)
    {
        s[i]=tao(a[i]);
    }
    for(int i=1;i<=n;i++)
        printf("%lld ",s[i]);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章