需要用树状数组维护01序列前缀和,并且查找某个位置的前缀和是k,也就是前面有k个1
这个可以用二分,两个log,但是用倍增就是一个log
不得不说树状数组和倍增的相性真的很好,倍增到的节点维护信息与上一级完全没有重合
譬如说跳8可以跳到8,跳4的时候如果可以跳12直接加上c[12]就可以,因为c[12]维护的是c[9]到c[12]
#include<bits/stdc++.h>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<iostream>
#include<math.h>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
#include<bitset>
using namespace std; //
#define ll long long
#define ull unsigned long long
#define pb push_back
#define FOR(a) for(int i=1;i<=a;i++)
#define sqr(a) (a)*(a)
#define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
ll qp(ll a,ll b,ll mod){
ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t;
}
struct DOT{ll x;ll y;};
inline void read(int &x){int k=0;char f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())k=k*10+c-'0';x=k*f;}
const int dx[4]={0,0,-1,1};
const int dy[4]={1,-1,0,0};
const int inf=0x3f3f3f3f;
const ll Linf=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;;
const int maxn=1e5+34;
int n;
int a[maxn],b[maxn],c[maxn*2],h[maxn];
int lowbit(int x){return x&-x;}
int ask(int x){
int ans=0;
for(;x;x-=lowbit(x))ans+=c[x];
return ans;
}
void add(int x,int y){
for(;x<=n;x+=lowbit(x))c[x]+=y;
}
int main(){
scanf("%d",&n);
for(int i=2;i<=n;i++){scanf("%d",&a[i]);}
for(int i=1;i<=n;i++){b[i]=1;add(i,1);}
int lim=(int)log2(n);
for(int i=n;i>=1;i--){
int ans=0,sum=0;
for(int p=lim;p>=0;p--){
if(ans + (1<<p) <=n && sum+c[ans+(1<<p)]<=a[i]){
sum+=c[ans+(1<<p)];
ans+=(1<<p);
}
}
h[i]=ans+1;
add(ans+1,-1);
}
for(int i=1;i<=n;i++)printf("%d\n",h[i]);
}