ZYB's Premutation
ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutation,now he ask you to
restore the premutation.
Pair (i,j)(i<j) is considered as a reverse log if Ai>Aj is matched.
Input
In the first line there is the number of testcases T.
For each teatcase:
In the first line there is one number N.
In the next line there are N numbers Ai,describe the number of the reverse logs of each prefix,
The input is correct.
1≤T≤5,1≤N≤50000
Output
For each testcase,print the ans.
Sample Input
1
3
0 1 2
Sample Output
3 1 2
Topic: Give the array A of prefix inverse order pairs, construct a sequence, satisfy this condition.
Thought: Construct from the back to the front, the initial number is 1 ~ n. It's easy to know that A[i] − A[i − 1] A[i] - A[i-1] A[i] − A[i − 1] gets the contribution of the number of position iii to the inverse logarithm of the whole iii prefix. Then A[i] − A[i − 1] + 1A[i] - A[i-1] + 1A[i] − A[i − 1] + 1 gets the number of positions iii that are currently unused. Just use the weight line tree to maintain this thing.
Code:
#include<bits/stdc++.h> #define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl #define pii pair<int,int> #define clr(a,b) memset((a),b,sizeof(a)) #define rep(i,a,b) for(int i = a;i < b;i ++) #define pb push_back #define MP make_pair #define LL long long #define ull unsigned LL #define ls i << 1 #define rs (i << 1) + 1 #define fi first #define se second #define ptch putchar #define CLR(a) while(!(a).empty()) a.pop() using namespace std; inline LL read() { LL s = 0,w = 1; char ch = getchar(); while(!isdigit(ch)) { if(ch == '-') w = -1; ch = getchar(); } while(isdigit(ch)) s = s * 10 + ch - '0',ch = getchar(); return s * w; } inline void write(LL x) { if(x < 0) putchar('-'), x = -x; if(x > 9) write(x / 10); putchar(x % 10 + '0'); } #ifndef ONLINE_JUDGE clock_t prostart = clock(); #endif const int maxn = 5e4 + 10; int a[maxn],ans[maxn]; int sum[maxn << 2]; void build(int l,int r,int i){ if(l == r){ sum[i] = 1; return ; } int mid = (l + r) >> 1; build(l,mid,ls); build(mid + 1,r,rs); sum[i] = sum[ls] + sum[rs]; } void update(int l,int r,int pos,int i){ if(l == r){ -- sum[i]; return ; } int mid = (l + r) >> 1; if(pos <= mid) update(l,mid,pos,ls); if(pos > mid) update(mid + 1,r,pos,rs); sum[i] = sum[ls] + sum[rs]; } int query(int l,int r,int i,int k){ if(l == r) return l; int mid = (l + r) >> 1; if(sum[rs] >= k) return query(mid + 1,r,rs,k); else return query(l,mid,ls,k - sum[rs]); } int main() { #ifndef ONLINE_JUDGE // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif int t = read(); while(t --){ int n = read(); build(1,n,1); for(int i = 1;i <= n;++ i) a[i] = read(); for(int i = n;i >= 1;-- i){ int k = a[i] - a[i - 1] + 1; ans[i] = query(1,n,1,k); update(1,n,ans[i],1); } for(int i = 1;i <= n;++ i){ write(ans[i]); ptch(i == n ? '\n' : ' '); } } #ifndef ONLINE_JUDGE cout << "time: " << 1.0 * (clock() - prostart) / CLOCKS_PER_SEC << " s" << endl; #endif return 0; }