D. Sorting By Multiplication

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 1lrn, and multiply every ai such that lir 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 a1<a2<<an must be satisfied).

Input

The first line contains a single integer t (1t104) — the number of test cases.

The first line of each test case contains one integer n (1n2105) — the length of the array a.

The second line of each test case contains n integers a1,a2,,an (1ai109) — the array a.

Additional constraint on the input: the sum of n over all test cases does not exceed 2105.

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种,全是正数,全是负数,某个前缀是负数剩下的是正数。

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

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

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

  另外如果最终所有元素均为正数,那么需要执行的操作次数就是s1[n]。如果最终所有元素均为正数,那么需要执行的操作次数就是s2[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

posted @   onlyblues  阅读(85)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2022-09-02 环形石子合并
Web Analytics
点击右上角即可分享
微信分享提示