小王在上算法设计与分析的课程中首次接触到插入排序,插入排序的基本原理如下:
给定数组,假如有序,考虑将 插入到有序子数组中. 用一个辅助变量记录 ,即 . 接下来,我们从索引 逆向遍历到 ,如果发现 ,则将 移动到 ,直到找到索引,使得 , 将 插入到 中, 即 .显然, 保持有序。迭代上述过程,直到插入最后一个元素 , 以使得数组 有序.
此外,插入排序的C语言代码如下:
void insertionSort(int a[], int n) {
for (int i = 2; i <= n; i++) {
int key = a[i];
int j = i - 1;
while (j >= 1 && a[j] > key) {
a[j + 1] = a[j];
j--;
}
a[j + 1] = key;
}
}
小王微调上述代码并定义一个 函数以估算插入排序的计算量,其代码如下:
int calc(int a[], int n) {
int total = 0;
for (int i = 2; i <= n; i++) {
int key = a[i];
int j = i - 1;
while (j >= 1 && a[j] > key) {
a[j + 1] = a[j];
j--;
total += 1;
}
a[j + 1] = key;
}
return total;
}
基于上述灵感,小王决定出一道校赛题,题目描述如下:
给定一个 长的整数数组 ,要求计算 . 小王认为该问题太简单了(直接套用上述代码即可, hah),因此决定加大题目难度。
增加 次修改操作,每次操作在数组的末尾插入新元素 。注意,修改操作是持久的。 每次修改数组后,计算一次 . ( 表示修改后的数组, 表示修改后的数组长度)