ZYB's Premutation
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 554 Accepted Submission(s): 271
Total Submission(s): 554 Accepted Submission(s): 271
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.
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
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
Source
题意: HDU上有中文题面,题意我就不呵呵了
题解: 很容易想到,从数组后面往前推,因为最后一个数我们可以确定其位置,接下来就是代码优化问题。直接暴力跑的话是会超时的。这题我用的是二分位置,加区间树状数组验证答案。
AC代码:
import java.util.*;
import java.io.*;
public class main{
static Scanner cin = new Scanner(System.in);
static PrintWriter out = new PrintWriter(System.out);
static int[] a = new int[50005];
static int[] c = new int[50005];
static int n;
public static void main(String[] args) throws IOException{
int T = cin.nextInt();
while(T-- > 0) {
int pre = -1,now;
n = cin.nextInt();
for(int i = 1; i <= n; i++) {
a[i] = cin.nextInt();
if(pre == -1) pre = a[i];
else {
now = a[i] - pre;
pre = a[i];
a[i] = now;
}
}
Arrays.fill(c, 0);
for(int i = n; i >= 1; i--) {
int l = 1,r = n,ans = 0;
while(l <= r) {
int mid = l + r >> 1;
int tp = n - mid - que(mid + 1, n);
if(tp > a[i] || tp == a[i] && que(mid, mid) == 0) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
a[i] = ans;
add(ans);
}
boolean ok = false;
for(int i = 1; i <= n; i++) {
if(ok) System.out.print(' ');
else ok = true;
System.out.print(a[i]);
}
System.out.println();
}
}
public static void add(int x) {
while(x <= n) {
c[x]++;
x += x & -x;
}
}
public static int que(int l,int r) {
int s = 0;
if(l > r) return s;
while(r > 0) {
s += c[r];
r -= r & -r;
}
l--;
while(l > 0) {
s -= c[l];
l -= l & -l;
}
return s;
}
}