Codeforces Round 744 (Div. 3) E2. Array Optimization by Deque

Array Optimization by Deque

time limit per test: 2 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

In fact, the problems E1 and E2 do not have much in common. You should probably think of them as two separate problems.

You are given an integer array a [ 1 … n ] = [ a 1 , a 2 , … , a n ] a[1 \ldots n] = [a_1, a_2, \ldots, a_n] a[1n]=[a1,a2,,an].

Let us consider an empty deque (double-ended queue). A deque is a data structure that supports adding elements to both the beginning and the end. So, if there are elements [ 3 , 4 , 4 ] [3, 4, 4] [3,4,4] currently in the deque, adding an element 1 1 1 to the beginning will produce the sequence [ 1 , 3 , 4 , 4 ] [{\color{red}{1}}, 3, 4, 4] [1,3,4,4], and adding the same element to the end will produce [ 3 , 4 , 4 , 1 ] [3, 4, 4, \color{red}{1}] [3,4,4,1].

The elements of the array are sequentially added to the initially empty deque, starting with a 1 a_1 a1 and finishing with a n a_n an. Before adding each element to the deque, you may choose whether to add it to the beginning or to the end.

For example, if we consider an array a = [ 3 , 7 , 5 , 5 ] a = [3, 7, 5, 5] a=[3,7,5,5], one of the possible sequences of actions looks like this:

1.add 3 3 3 to the beginning of the deque:deque has a sequence [ 3 ] [\color{red}{3}] [3] in it;
2.add 7 7 7 to the end of the deque:deque has a sequence [ 3 , 7 ] [3, \color{red}{7}] [3,7] in it;
3.add 5 5 5 to the end of the deque:deque has a sequence [ 3 , 7 , 5 ] [3, 7, \color{red}{5}] [3,7,5] in it;
4.add 5 5 5 to the beginning of the deque:deque has a sequence [ 5 , 3 , 7 , 5 ] [{\color{red}{5}}, 3, 7, 5] [5,3,7,5] in it;

Find the minimal possible number of inversions in the deque after the whole array is processed.

An inversion in sequence d d d is a pair of indices ( i , j ) (i, j) (i,j) such that i < j i < j i<j and d i > d j d_i > d_j di>dj. For example, the array d = [ 5 , 3 , 7 , 5 ] d = [5, 3, 7, 5] d=[5,3,7,5] has exactly two inversions — ( 1 , 2 ) (1, 2) (1,2) and ( 3 , 4 ) (3, 4) (3,4), since d 1 = 5 > 3 = d 2 d_1 = 5 > 3 = d_2 d1=5>3=d2 and d 3 = 7 > 5 = d 4 d_3 = 7 > 5 = d_4 d3=7>5=d4.

Input

The first line contains an integer t t t ( 1 ≤ t ≤ 1000 1 \leq t \leq 1000 1t1000) — the number of test cases.

The next 2 t 2t 2t lines contain descriptions of the test cases.

The first line of each test case description contains an integer n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \le n \le 2 \cdot 10^5 1n2105) — array size. The second line of the description contains n n n space-separated integers a i a_i ai ( − 1 0 9 ≤ a i ≤ 1 0 9 -10^9 \le a_i \le 10^9 109ai109) — elements of the array.

It is guaranteed that the sum of n n n over all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2105.

Output

Print t t t lines, each line containing the answer to the corresponding test case. The answer to a test case should be a single integer — the minimal possible number of inversions in the deque after executing the described algorithm.

Example

i n p u t \tt input input
6
4
3 7 5 5
3
3 2 1
3
3 1 2
4
-1 2 2 -1
4
4 5 1 3
5
1 3 1 3 2
o u t p u t \tt output output
2
0
1
0
1
2

Note

One of the ways to get the sequence [ 5 , 3 , 7 , 5 ] [5, 3, 7, 5] [5,3,7,5] in the deque, containing only two inversions, from the initial array [ 3 , 7 , 5 , 5 ] [3, 7, 5, 5] [3,7,5,5] (the first sample test case) is described in the problem statement.

Also, in this example, you could get the answer of two inversions by simply putting each element of the original array at the end of the deque. In this case, the original sequence [ 3 , 7 , 5 , 5 ] [3, 7, 5, 5] [3,7,5,5], also containing exactly two inversions, will be in the deque as-is.

Tutorial

由题意得,每个元素有两种添加方式,要么添加在前面,要么添加在后面,并且放到前面,带来的逆序对数量是是当前数组中比它小的数的个数;放到后面,带来的逆序对数量是当前数组中比它大的数的个数,所以,产生的新逆序对数量只跟前 k k k 个元素中几个比当前数 a i a_i ai 大有关,且每个元素产生的新的逆序对数量是相互独立的,最后答案是 ∑ i = 0 n ( a i  所贡献的逆序对 ) \sum_{i = 0}^n (a_i\ 所贡献的逆序对) i=0n(ai 所贡献的逆序对),综上所述,对于每个元素 a i a_i ai,只需要取 min ⁡ ( 比  a i  小的元素个数,比  a i  大的元素个数 ) \min(比\ a_i\ 小的元素个数,比\ a_i\ 大的元素个数) min( ai 小的元素个数,比 ai 大的元素个数)

可以用树状数组来解决这个问题,可以快速查询前可以快速查找区间内的值的个数

此解法时间复杂度为 O ( n log ⁡ n ) \mathcal O(n\log n) O(nlogn)

Solution

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long
#define lowbit(x) x & -x

struct Tree {
    vector<int> tree;
    
    Tree() {}
    Tree(int n) {
        tree.resize(n + 11);
    }
    
    void update(int i, int x) {
        while (i < tree.size()) {
            tree[i] += x;
            i += lowbit(i);
        }
    }
    
    int query(int i) {
        int ans = 0;
        while (i) {
            ans += tree[i];
            i -= lowbit(i);
        }
        return ans;
    }
};

void solve() {
    int n, ans = 0;
    cin >> n;
    Tree tree(n);
    vector<int> a(n);
    for (int &ai : a) {
        cin >> ai;
    }
    vector<int> b(a);
    ranges::sort(b);
    b.erase(unique(b.begin(), b.end()), b.end());
    map<int, int> idx;
    for (int i = 0; i < b.size(); ++i) {
        idx[b[i]] = i + 1;
    }
    for (int i = 0; i < n; ++i) {
        ans += min(tree.query(idx[a[i]] - 1), tree.query(n) - tree.query(idx[a[i]]));
        tree.update(idx[a[i]], 1);
    }
    cout << ans << endl;
}

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    cout << fixed << setprecision(15);
    int Test; cin >> Test; while (Test--)
    solve();
    return 0;
}
  • 27
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值