传送门:http://codeforces.com/problemset/problem/1208/D
大水题= =,比C的构造不知道水到哪里去了
从后往前考虑,最后一个s[n]一定就是比a[n]小的所有数字的和,所以可以直接算出a[n]。
接下来,s[n-1]是去掉a[n]之后的情况下,比a[n-1]小的所有数字的和,我们也可以知道a[n-1]的值
这样用一个树状数组维护一下去掉后面已经确定的数字,当前情况下的前缀和即可
#include<bits/stdc++.h>
#define maxl 200010
using namespace std;
int n;
long long a[maxl],s[maxl];
long long b[maxl];
inline void add(int i,int x)
{
while(i<=n)
{
b[i]+=x;
i+=i&-i;
}
}
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&s[i]);
for(int i=1;i<=n;i++)
add(i,i);
}
inline long long find(long long mid)
{
long long sum=0,ret=0;
int up=log2(n),d=1<<up;
for(int i=up;i>=0;i--)
{
if(sum+b[ret+d]<=mid && ret+d<n)
{
sum+=b[ret+d];
ret+=d;
}
d=d>>1;
}
return ret+1;
}
inline void mainwork()
{
long long sum=0;
for(int i=n;i>=1;i--)
{
a[i]=find(s[i]);
add(a[i],-a[i]);
}
}
inline void print()
{
for(int i=1;i<=n;i++)
printf("%lld ",a[i]);
}
int main()
{
prework();
mainwork();
print();
return 0;
}