HDU5592-ZYB's Premutation

来源:互联网 发布:淘宝怎么投诉卖家手机 编辑:程序博客网 时间:2024/06/06 01:37

ZYB's Premutation

                                                                    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
                                                                                            Total Submission(s): 1085    Accepted Submission(s): 569


Problem Description
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.

1T5,1N50000
 

Output
For each testcase,print the ans.
 

Sample Input
130 1 2
 

Sample Output
3 1 2
 

Source
BestCoder Round #65
 

Recommend
hujie
 


题意:有一个序列,现在知道这个序列所有前缀的逆序对数,还原出这个序列

解题思路:a[i]-a[i-1]表示第i个数前面比它大的数字个数。用i-(a[i]-a[i-1])表示i个数中比第i个数小的个数,倒着跑,线段树维护每个区间还剩多少数字


#include <iostream>  #include <cstdio>  #include <string>  #include <cstring>  #include <cmath> #include <algorithm>#include <queue>  #include <vector>  #include <set>  #include <stack>  #include <map>  #include <climits>  using namespace std;#define LL long long  const int INF = 0x3f3f3f3f;int t, n;int a[50009], sum[50009 << 2], ans[50009];void build(int k, int l, int r){sum[k] = r - l + 1;if (l == r) return;int mid = (l + r) >> 1;build(k << 1, l, mid), build(k << 1 | 1, mid + 1, r);}int query(int k, int l, int r, int p){sum[k]--;if (l == r) return l;int mid = (l + r) >> 1;if (sum[k << 1] >= p) return query(k << 1, l, mid, p);else return query(k << 1 | 1, mid + 1, r, p - sum[k << 1]);}int main(){scanf("%d", &t);while (t--){scanf("%d", &n);a[0] = 0;for (int i = 1; i <= n; i++) scanf("%d", &a[i]);build(1, 1, n);for (int i = n, j = 0; i >= 1; i--, j++){int p = a[i] - a[i - 1] + 1;p = n - j - p + 1;ans[n - j] = query(1, 1, n, p);}printf("%d", ans[1]);for (int i = 2; i <= n; i++) printf(" %d", ans[i]);printf("\n");}return 0;}

原创粉丝点击