就是给一个n个数的全排,然后bi记录比ai小且在排在ai前面的数的和,求ai
树状数组维护,二分
#include<bits/stdc++.h> using namespace std; #define int long long #define si signed #define endl ' ' #define sc(x) scanf("%I64d",&x); #define read(A) for(int i=1;i<=n;i++)scanf("%I64d",&A[i]); #define P pair<int,int> #define fi first #define se second #define ot(x) cout<<x<<' '; #define maxn 200000+500 int A[maxn]; int n,t,x,y,a,b; int c[maxn]; int ans[maxn]; bool B[maxn]; int lowbit(int x) { return x&(-x); } void add(int i,int k) { while(i <= n+100) { c[i] += k; i += lowbit(i); } } int get(int i) { int res = 0; while(i > 0) { res += c[i]; i -= lowbit(i); } return res; } int solve(int x) { int l=1,r=n; int mid; while(l+1<r) { mid=(l+r)/2; if(get(mid-1)<=x){ l=mid; }else if(get(mid-1)>x){ r=mid-1; } } int ans; if(get(r-1)==x){ ans=r; }else ans=l; return ans; } signed main() { sc(n); for(int i=1;i<=n;i++){ sc(A[i]); add(i,i); } // int _j=1; for(int i=n; i>0; i--) { if(A[i]==0) { for(_j; _j<=n; _j++) { if(!B[_j]) { ans[i]=_j; add(_j,-_j); B[_j]=1; break; } } } else { ans[i]=solve(A[i]); B[ans[i]]=1; // cout<<ans[i]<<' '; add(ans[i],-ans[i]); } } for(int i=1; i<=n; i++) { cout<<ans[i]<<' '; } }