赛时随便写了个做法,看standing,发现很多人的做法也是很奇特
赛后看了官方题解。。翻译下
题意:
每次可以给一个任意的后缀里的所有数
+
i
+i
+i
执行n次。
使得逆序对最少。
思路:
tip1:
什么时候逆序对最少?
序列非递减。
解法:
处理出差分数组
d
=
[
a
2
−
a
1
,
a
3
−
a
2
,
.
.
.
,
a
n
−
a
n
−
1
]
d = [a_2-a_1,a_3-a_2,...,a_n-a_{n-1}]
d=[a2−a1,a3−a2,...,an−an−1]
那么什么时候序列非递减?转换为差分数组都是非负。
由
d
i
=
a
i
+
1
−
a
i
,
i
∈
[
1
,
n
−
1
]
d_i = a_{i+1}-a_{i} ,i\in[1,n-1]
di=ai+1−ai,i∈[1,n−1]
显然
d
i
≥
−
a
i
d_i \ge -a_i
di≥−ai
那么我们可以对位置
i
+
1
i+1
i+1开始的后缀
+
a
i
+a_i
+ai.
由于每个
a
i
a_i
ai都是唯一的,所以可以构造出非递减序列。
最后输出的时候,注意 i = n i=n i=n时,就另 a n s [ a [ i ] ] = n ans[a[i]] = n ans[a[i]]=n即可。
AC(Java)
package com.hgs.codeforces.contest.globalround.contest23.c2;
/**
* @author youtsuha
* @version 1.0
* Create by 2022/10/16 14:13
*/
import java.util.*;
import java.io.*;
public class Main {
static FastScanner cin;
static PrintWriter cout;
private static void init()throws IOException {
cin = new FastScanner(System.in);
cout = new PrintWriter(System.out);
}
private static void close(){
cout.close();
}
private static void sol()throws IOException {
int n = cin.nextInt();
int a[] = new int[n];
for(int i = 0; i < n; i ++ ) {
int p = cin.nextInt();
p--;
a[p] = (i + 1) + 1;
}
for(int i = 0; i < n; i ++ ) cout.print(Math.min(a[i],n) + " ");
cout.println();
}
public static void main(String[] args) throws IOException {
init();
int tt = cin.nextInt();
while(tt -- > 0)sol();
close();
}
}
class FastScanner {
BufferedReader br;
StringTokenizer st = new StringTokenizer("");
public FastScanner(InputStream s) {
br = new BufferedReader(new InputStreamReader(s));
}
public FastScanner(String s) throws FileNotFoundException {
br = new BufferedReader(new FileReader(new File(s)));
}
public String next() throws IOException {
while (!st.hasMoreTokens()){
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) { e.printStackTrace(); }
}
return st.nextToken();
}
public int nextInt() throws IOException {
return Integer.parseInt(next());
}
public long nextLong() throws IOException {
return Long.parseLong(next());
}
public double nextDouble() throws IOException {
return Double.parseDouble(next());
}
}