ZYB's Premutation
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 638 Accepted Submission(s): 302
Problem Description
restore the premutation.
Pair
Input
In the first line there is the number of testcases T.
For each teatcase:
In the first line there is one numberN .
In the next line there areN numbers Ai ,describe
the number of the reverse logs of each prefix,
The input is correct.
1≤T≤5 ,1≤N≤50000
For each teatcase:
In the first line there is one number
In the next line there are
The input is correct.
Output
For each testcase,print the ans.
Sample Input
1 3 0 1 2
Sample Output
3 1 2
题目链接:点击打开链接
能够想到a[i] - a[i - 1]为i前比a[i]大的数的个数, 从后向前遍历, 通过二分与树状数组确定i应当填入的位置.
AC代码:
#include "iostream" #include "cstdio" #include "cstring" #include "algorithm" #include "queue" #include "stack" #include "cmath" #include "utility" #include "map" #include "set" #include "vector" #include "list" #include "string" using namespace std; typedef long long ll; const int MOD = 1e9 + 7; const int INF = 0x3f3f3f3f; const int MAXN = 5e4 + 5; int n, a[MAXN], c[MAXN], ans[MAXN]; int lowbit(int x) { return x & (-x); } void update(int x, int y) { while(x <= n) { c[x] += y; x += lowbit(x); } } int get_sum(int x) { int sum = 0; while(x > 0) { sum += c[x]; x -= lowbit(x); } return sum; } int binary_search(int x) { int l = 1, r = n, m; while(l <= r) { m = (l + r) >> 1; if(get_sum(m) >= x) r = m - 1; else l = m + 1; } return l; } int main(int argc, char const *argv[]) { int t; scanf("%d", &t); while(t--) { memset(c, 0, sizeof(c)); memset(ans, 0, sizeof(ans)); scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); for(int i = n; i >= 1; --i) a[i] -= a[i - 1]; for(int i = 1; i <= n; ++i) update(i, 1); for(int i = n; i >= 1; --i) { int pos = i - a[i] - 1; ans[i] = binary_search(pos + 1); update(ans[i], -1); } for(int i = 1; i < n; ++i) printf("%d ", ans[i]); printf("%d ", ans[n]); } return 0; }