Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) D

D. Restore Permutation

题链
不难看出我们应该从后往前做
我们设t[i]=i*(i-1)/2
最后一个i肯定能在t数组直接找到
比如我们找到了是3
那么要是我们下一个是5
我们就要把这个3从以后的t[4] t[5] ....中剪掉
注意这里剪掉之后我们t还是保持单调性 这里我们应该很敏感的可以知道查找一个t=a[i]可以用二分了
注意code里t[i]数组是tr[i]的前缀和

int n,tr[N];
int lowbit(int x){return x&-x;}
void add(int x,int c){
    for(int i=x;i<=n;i+=lowbit(i)){
        tr[i]+=c;
    }
}
int query(int x){
    int res=0;
    for(int i=x;i;i-=lowbit(i)){
        res+=tr[i];
    }
    return res;
}
void solve(){
    cin>>n;
    vector<int>a(n+1),ans(n+1);
    for(int i=1;i<=n;i++)cin>>a[i],add(i,i);
    for(int i=n;i>=1;i--){
        int l=1,r=n;
        while(l<r){
            int mid=(l+r+1)>>1;
            if(query(mid-1)<=a[i])l=mid;
            else r=mid-1;
        }
        ans[i]=l;
        add(l,-l);
    }
    for(int i=1;i<=n;i++)cout<<ans[i]<<' ';
}
posted @ 2022-12-25 22:15  ycllz  阅读(21)  评论(0)    收藏  举报