首页 > 其他分享 >D. Sorting By Multiplication

D. Sorting By Multiplication

时间:2023-09-02 16:23:08浏览次数:41  
标签:case 10 le test Sorting Multiplication array 正数

D. Sorting By Multiplication

You are given an array $a$ of length $n$, consisting of positive integers.

You can perform the following operation on this array any number of times (possibly zero):

  • choose three integers $l$, $r$ and $x$ such that $1 \le l \le r \le n$, and multiply every $a_i$ such that $l \le i \le r$ by $x$.

Note that you can choose any integer as $x$, it doesn't have to be positive.

You have to calculate the minimum number of operations to make the array $a$ sorted in strictly ascending order (i. e. the condition $a_1 < a_2 < \dots < a_n$ must be satisfied).

Input

The first line contains a single integer $t$ ($1 \le t \le 10^4$) — the number of test cases.

The first line of each test case contains one integer $n$ ($1 \le n \le 2 \cdot 10^5$) — the length of the array $a$.

The second line of each test case contains $n$ integers $a_1, a_2, \dots, a_n$ ($1 \le a_i \le 10^9$) — the array $a$.

Additional constraint on the input: the sum of $n$ over all test cases does not exceed $2 \cdot 10^5$.

Output

For each test case, print one integer — the minimum number of operations required to make $a$ sorted in strictly ascending order.

Example

input

3
5
1 1 2 2 2
6
5 4 3 2 5 1
3
1 2 3

output

3
2
0

Note

In the first test case, we can perform the operations as follows:

  • $l = 2$, $r = 4$, $x = 3$;
  • $l = 4$, $r = 4$, $x = 2$;
  • $l = 5$, $r = 5$, $x = 10$.

After these operations, the array $a$ becomes $[1, 3, 6, 12, 20]$.
In the second test case, we can perform one operation as follows:

  • $l = 1$, $r = 4$, $x = -2$;
  • $l = 6$, $r = 6$, $x = 1337$.

After these operations, the array $a$ becomes $[-10, -8, -6, -4, 5, 1337]$.
In the third test case, the array $a$ is already sorted.

 

解题思路

  首先最终结果无法就只有$3$种,全是正数,全是负数,某个前缀是负数剩下的是正数。

  如果最终所有元素均为正数,那么从头开始遍历数组,如果发现$a_i \geq a_{i+1}$,那么至少要执行一次操作使得$a_i < a_{i+1}$。由于此时$1 \sim i$已经满足严格递增的关系,那么我们令后缀$i+1 \sim n$均乘上一个正数,使得$a_i < a_{i+1}$且后缀的元素相对大小不变。由于乘上的数是正数,因此结果只会变大,如果改变的后缀的元素的相对大小(即不选择整个后缀乘上这个数),那么只会让某个位置的前一个数变大而后一个数变小,这样反而还要再执行多一次操作。

  如果最终所有元素均为负数,那么除了让整个序列变成严格递增外还要将每个数变成负数,可以等价于先将整个序列变成严格递减,再将整个序列乘上一个负数。与上面的做法类似,从头开始遍历,如果发现$a_i \leq a_{i+1}$,由于乘上一个正数会使得结果变大,因此将整个前缀$1 \sim i$乘上一个正数即可。

  如果最终某个前缀是负数,后缀是正数,那么我们可以枚举分界点是哪个,然后将分界点前的元素按上面的做法变成严格递增的负数,再将分界点后的元素按上面的做法变成严格递增的正数。在枚举分界点后为了能在$O(1)$的复杂度得到结果,我们需要快速知道某个前缀有多少个相邻的数对满足$a_i \leq a_{i+1}$以及某个后缀有多少个相邻的数对满足$a_i \geq a_{i+1}$。假设我们预处理得到前缀和$s_1[i]$表示$i \in [1 \sim i)$满足$a_i \geq a_{i+1}$的个数,$s_2[i]$表示$i \in [1 \sim i)$满足$a_i \leq a_{i+1}$的个数,如果分界点是$i$,那么需要执行的操作总数量就是$(s_2[i] + 1) + (s_1[n] - s_1[i+1])$。

  另外如果最终所有元素均为正数,那么需要执行的操作次数就是$s_1[n]$。如果最终所有元素均为正数,那么需要执行的操作次数就是$s_2[n]+1$。

  AC代码如下,时间复杂度为$O(n)$:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 2e5 + 10;
 7 
 8 int a[N];
 9 int s1[N], s2[N];
10 
11 void solve() {
12     int n;
13     scanf("%d", &n);
14     for (int i = 1; i <= n; i++) {
15         scanf("%d", a + i);
16     }
17     for (int i = 2; i <= n; i++) {
18         s1[i] = s1[i - 1], s2[i] = s2[i - 1];
19         if (a[i - 1] >= a[i]) s1[i]++;
20         if (a[i - 1] <= a[i]) s2[i]++;
21     }
22     int ret = min(s1[n], s2[n] + 1);
23     for (int i = 1; i < n; i++) {
24         ret = min(ret, s2[i] + 1 + s1[n] - s1[i + 1]);
25     }
26     printf("%d\n", ret);
27 }
28 
29 int main() {
30     int t;
31     scanf("%d", &t);
32     while (t--) {
33         solve();
34     }
35     
36     return 0;
37 }

 

参考资料

  Educational Codeforces Round 154 (Rated for Div. 2)(ABCD)(模拟/思维):https://zhuanlan.zhihu.com/p/653627595

  Educational Codeforces Round 154 Editorial:https://codeforces.com/blog/entry/119964

标签:case,10,le,test,Sorting,Multiplication,array,正数
From: https://www.cnblogs.com/onlyblues/p/17673797.html

相关文章

  • 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}^{......
  • UVA11714 Blind Sorting 题解
    题目链接思路一道结论题,代码实现非常简单。把此题拆分成两个小问题。在最坏的情况下,需要几次询问,才能找出最大的数。在最坏的情况下,需要几次询问,才能找出次大数。对于找出最大的数,可以模拟二分查找来解决,每次将左边界右移或右边界左移,最终得到最大数。因此在最坏的情......
  • CF1682B AND Sorting 题解
    首先,我们按照题意,可以用0来作为中间的一个数来交换其他两个数,这种元素肯定是有的,那就是所有不在正确位置上的所有数的AND值,我们可以开一个数组a来模拟这个过程,a_i&a_j=X,那这里的X就起到我们的0的作用了。代码:#include<bits/stdc++.h>#defineintlonglongusin......
  • 题解 POJ3318【Matrix Multiplication】
    postedon2022-10-2119:56:08|under题解|sourceproblem判断三个\(n\timesn\)的矩阵是否满足\(A\timesB=C\),\(n\leq500\)。solution随机一个行向量\(v\)。若\(a\timesb=c\),则有\(v\timesa\timesb=v\timesc\)(不充分)。显然相乘复杂度仅为\(O(n^2)\)。类似于......
  • leetcode -- Maximum Gap -- 与distributed sorting有关,重点复习一下
    https://leetcode.com/problems/maximum-gap/sort算法除了比较算法之外,还有distributedsort,时间效率可以优于O(nlogn),甚至可以达到O(n).包括coutingsort,bucketsort,radixsort.复习这三种的原理。参考https://www.byvoid.com/blog/sort-radix这里对于bucketsort,提到可能......
  • Faster sorting algorithms discovered using deep reinforcement learning
    摘要:AlphaDev模型优化排序算法,将排序算法提速70%。通过强化学习,AlphaDev发现了更加有效的算法,直接超越了科学家和工程师们几十年来的精心打磨。现在,新的算法已经成为两个标准C++编码库的一部分,每天都会被全球的程序员使用数万亿次。介绍优化目标为排序算法的CPU延迟时间......
  • HDU 2838 Cow Sorting(树状数组)
    题意:首先每次只能交换相邻的两头牛,并且最后要求升序排列,所以最后整个序列的逆序是0,每次交换只可以消除1个逆序。(令a[i]的逆序是从1到i-1比它大的数的个数。)思路:对于某个数,要把它变成有序的,那么很容易可以推算出公式就是它自身的逆序数乘自身的值再加上它的逆序数的和,自己算算看看。......
  • [Codeforces Round 876 (Div. 2)][Codeforces 1839D. Ball Sorting]
    题目链接:D-BallSorting题目大意:需要对一个排列按照指定操作进行排序。操作一:在数字间插入一个特殊点,可执行不超过\(k\)次;操作二:将在特殊点旁的数移动到任意位置。所有操作结束后特殊点会消失,要求对所有\(k\in[1,n]\),求出操作二的最少操作次数。分析题意可以得出,操作一放......
  • 1839D - Ball Sorting (dp)
    题意:有一个1~n的序列,求放k个0后,最小操作次数,使得去掉0后序列升序,每次操作;可以把与0相邻的数,放到任意位置思路:因为n最大到500,并且求k属于1~n的所有最小代价,所以考虑dpdp[i][j],i表示以ai结尾放j个0的最小代价最小代价等于去掉以ai结尾升序列后,剩余子段用j个区间覆盖,的最小值......
  • CodeForces 1827 B Range Sorting
    洛谷传送门CF传送门考虑拆贡献\(i-1\simi\),发现当\([1,i-1]\)的最大值大于\([i,n]\)的最小值时\(i-1\simi\)产生\(1\)的贡献。考虑枚举左端点\(j\),设\(x=\max\limits_{k=j}^{i-1}a_k\)。设\(i\)及\(i\)以后第一个\(<x\)的数位置是\(p\),那么......