B. Split Sort
You are given a permutation$^{\dagger}$ $p_1, p_2, \ldots, p_n$ of integers $1$ to $n$.
You can change the current permutation by applying the following operation several (possibly, zero) times:
- choose some $x$ ($2 \le x \le n$);
- create a new permutation by:
- first, writing down all elements of $p$ that are less than $x$, without changing their order;
- second, writing down all elements of $p$ that are greater than or equal to $x$, without changing their order;
- replace $p$ with the newly created permutation.
For example, if the permutation used to be $[6, 4, 3, 5, 2, 1]$ and you choose $x = 4$, then you will first write down $[3, 2, 1]$, then append this with $[6, 4, 5]$. So the initial permutation will be replaced by $[3, 2, 1, 6, 4, 5]$.
Find the minimum number of operations you need to achieve $p_i = i$ for $i = 1, 2, \ldots, n$. We can show that it is always possible to do so.
$^{\dagger}$ A permutation of length $n$ is an array consisting of $n$ distinct integers from $1$ to $n$ in arbitrary order. For example, $[2,3,1,5,4]$ is a permutation, but $[1,2,2]$ is not a permutation ($2$ appears twice in the array), and $[1,3,4]$ is also not a permutation ($n=3$ but there is $4$ in the array).
Input
Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1 \le t \le 1000$). The description of the test cases follows.
The first line of each test case contains one integer $n$ ($1 \le n \le 100\,000$).
The second line of each test case contains $n$ integers $p_1, p_2, \ldots, p_n$ ($1 \le p_i \le n$). It is guaranteed that $p_1, p_2, \ldots, p_n$ is a permutation.
It is guaranteed that the sum of $n$ over all test cases does not exceed $100\,000$.
Output
For each test case, output the answer on a separate line.
Example
input
5 1 1 2 2 1 6 6 4 3 5 2 1 3 3 1 2 19 10 19 7 1 17 11 8 5 12 9 4 18 14 2 6 15 3 16 13
output
0 1 4 1 7
Note
In the first test case, $n = 1$ and $p_1 = 1$, so there is nothing left to do.
In the second test case, we can choose $x = 2$ and we immediately obtain $p_1 = 1$, $p_2 = 2$.
In the third test case, we can achieve the minimum number of operations in the following way:
- $x = 4$: $[6, 4, 3, 5, 2, 1] \rightarrow [3, 2, 1, 6, 4, 5]$;
- $x = 6$: $[3, 2, 1, 6, 4, 5] \rightarrow [3, 2, 1, 4, 5, 6]$;
- $x = 3$: $[3, 2, 1, 4, 5, 6] \rightarrow [2, 1, 3, 4, 5, 6]$;
- $x = 2$: $[2, 1, 3, 4, 5, 6] \rightarrow [1, 2, 3, 4, 5, 6]$.
解题思路
首先很明显$x$可以从$2$枚举到$n$依次进行操作,那么至少$n-1$次就可以将整个序列变成升序。因此很自然会想到某些$x$是否没有必要进行操作。
当$x$从$2$枚举到$k$并完成操作后,此时恰好有$a_i = i, \, i \in [1,k-1]$。接着对$x=k+1$进行操作,而改变的地方只有将$a_k$变成$k$,让$k$在$k+1$的前面。如果$k$在$k+1$的前面,是否可以不进行$x=k+1$的操作呢?可以发现如果跳过$x=k+1$而对$x=k+2$进行操作,那么就会得到$a_i = i, \, i \in [1,k+1]$。因此如果发现$k$在$k+1$的前面,那么我们就可以跳过$x=k+1$的操作。而如果$k$在$k+1$的后面,那么必须要进行$x=k+1$的操作,否则永远无法将$k$变到$k+1$的前面。
因此记录初始时数组中每个数$i$的下标$p_i$,然后从小到大枚举每个数$i$,如果发现$p_i < p_{i+1}$,说明可以跳过$x=i+1$这个操作,否则进行。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 const int N = 1e5 + 10; 7 8 int p[N]; 9 10 void solve() { 11 int n; 12 scanf("%d", &n); 13 for (int i = 0; i < n; i++) { 14 int x; 15 scanf("%d", &x); 16 p[x] = i; 17 } 18 int ret = 0; 19 for (int i = 1; i < n; i++) { 20 if (p[i + 1] < p[i]) ret++; 21 } 22 printf("%d\n", ret); 23 } 24 25 int main() { 26 int t; 27 scanf("%d", &t); 28 while (t--) { 29 solve(); 30 } 31 32 return 0; 33 }
参考资料
Pinely Round 2 Editorial:https://codeforces.com/blog/entry/119902
标签:Sort,case,le,int,Split,permutation,test,first From: https://www.cnblogs.com/onlyblues/p/17669256.html