首页 > 其他分享 >B. Split Sort

B. Split Sort

时间:2023-08-31 12:22:09浏览次数:43  
标签:Sort case le int Split permutation test first

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:

  1. $x = 4$: $[6, 4, 3, 5, 2, 1] \rightarrow [3, 2, 1, 6, 4, 5]$;
  2. $x = 6$: $[3, 2, 1, 6, 4, 5] \rightarrow [3, 2, 1, 4, 5, 6]$;
  3. $x = 3$: $[3, 2, 1, 4, 5, 6] \rightarrow [2, 1, 3, 4, 5, 6]$;
  4. $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

相关文章

  • vue sort 排序
    Vue.js提供了多种实现排序的方式。下面列举了几种常见的排序方法及示例代码。 1、使用JavaScript原生的Array.prototype.sort()方法进行排序。这种方法适用于简单的数组排序需求。//在Vue组件中的方法中使用sort方法进行排序data(){return{myArray:[3,1,2,4......
  • webpack生产环境优化:code split
    转载请注明来源:http://www.eword.name/Author:ewordEmail:[email protected]生产环境优化:codesplitcodesplit代码分割,既将打包后的js分割成多份js文件,方便后期实现“并行加载”、“按需加载”等,提高性能。一、核心配置建议使用方式二的单入口模式,并按需使用......
  • CF258D Little Elephant and Broken Sorting 题解
    题意给定一个长度为\(n\)的排列\(a\)和\(m\)个形如\(\left(x,y\right)\)的操作,每次操作有\(50\%\)的概率交换\(a_x,a_y\),求最终排列的期望逆序对数。(\(1\len,m\le5000\))。题解首先转化答案\[\text{Ans}=\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{......
  • SortedSet实现点赞功能附带排行榜
    SortedSet的基本使用Sortedset也称Zset类型,是一种具有排序效果的set集合。它跟set集合一样也是string类型元素的集合,且不允许重复的成员。并且要求每个元素都会关联一个double类型的分数。后续可以通过分数来为集合中的成员进行从小到大的排序。Sortedset集合是通过哈希表......
  • split()方法的使用
    js中split()方法的使用split()方法是将字符串通过分隔符分隔成数组,例如:......
  • c++ stl std::sort使用例子
    classUser{public:int32_tm_fight_power;private:int32_tm_level;};boolCenterData::compare(constUser*left,constUser*right){if(left->m_fight_power!=right->m_fight_power){returnleft->m_fight_power>ri......
  • element+Sortable 实现表格拖拽
    <template><divclass="draggable"style="padding:20px"><el-tablerow-key="id":data="state.tableData"style="width:100%"><el-table-columnv-for="(item,......
  • 无涯教程-PHP - preg_split()函数
    preg_split()-语法arraypreg_split(stringpattern,stringstring[,intlimit[,intflags]]);preg_split()函数的操作与split()完全相同,只不过正则表达式被接受为pattern的输入参数。如果指定了可选的输入参数limit,则仅返回子字符串的限制数量。标志可以是以下标志......
  • pandas的分列操作str.split()
    本文主要是在pandas中如何对字符串进行切分。我们考虑一下下面的应用场景。 这个是我们的数据集(data),可以看到,数据集中某一列(name)是某个行业的分类。各个行业之间用符号‘|’分割。我们要把用每个‘|’进行分割的内容抽取出来。pandas有个一步到到位的方法,非常方便。impor......
  • AtCoder Beginner Contest 315 - E (toposort)
    目录E-PrerequisitesE-Prerequisites题意n本书,序号1~n。给定阅读每本书之前必须要看的书的序号。请你输出任意一种看第一本书所需看书数量最少的方法思路利用拓扑序列先对书之间的制约关系建图,再利用bfs找到包含书本1的连通块,再对全图进行拓扑排序得到拓扑序列......