题目链接:http://codeforces.com/contest/1208/problem/D
思路:从后往前确定,Sn=1+2.....(Pn)-1,所以可以直接得出最后一个Pn,然后再找Pn-1,
如果Pn-1大于Pn,Sn=1+2+..(Pn-1)-1
如果Pn-1小于Pn,Sn=1+2+...(Pn-1)-1-Pn
直接二分枚举Pi,用树状数组处理
#include<stdio.h>
#include<string.h>
#define ll long long
#include<algorithm>
using namespace std;
ll A[200010],T[200010],B[200010];
ll n;
ll lowbit(ll x)
{
return x&(-x);
}
ll add(ll pos,ll x)
{
while(pos<=n)
{
T[pos]+=x;
pos+=lowbit(pos);
}
}
ll sum(ll pos)
{
ll ans=0;
while(pos>0)
{
ans+=T[pos];
pos-=lowbit(pos);
}
return ans;
}
int main()
{
scanf("%I64d",&n);
for(ll i=1;i<=n;i++)
{
scanf("%I64d",&A[i]);
add(i+1,i);
}
for(ll i=n;i>0;i--)//从后往前枚举
{
ll l=1,r=n,mid;
while(l<=r)//二分
{
mid=(l+r)>>1;
if(sum(mid)>A[i]) r=mid-1;
else l=mid+1;
}
add(r+1,-r);
B[i]=r;
}
for(ll i=1;i<=n;i++)
printf("%I64d ",B[i]);
printf("\n");
}