AtCoder Regular Contest 120 C - Swaps 2(树状数组)

题目链接:点我点我

Score : 500 points

Problem Statement

Given are two sequences of length N each: A=(A1,A2,A3,,AN) and B=(B1,B2,B3,,BN).
Determine whether it is possible to make A equal B by repeatedly doing the operation below (possibly zero times). If it is possible, find the minimum number of operations required to do so.

  • Choose an integer i such that 1i<N, and do the following in order:
    • swap Ai and Ai+1;
    • add 1 to Ai;
    • subtract 1 from Ai+1.

Constraints

  • 2N2×105
  • 0Ai109
  • 0Bi109
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A1 A2 A3  AN
B1 B2 B3  BN

Output

If it is impossible to make A equal B, print -1.
Otherwise, print the minimum number of operations required to do so.


Sample Input 1

3
3 1 4
6 2 0

Sample Output 1

2

We can match A with B in two operations, as follows:

  • First, do the operation with i=2, making A=(3,5,0).
  • Next, do the operation with i=1, making A=(6,2,0).

We cannot meet our objective in one or fewer operations.


Sample Input 2

3
1 1 1
1 1 2

Sample Output 2

-1

In this case, it is impossible to match A with B.


Sample Input 3

5
5 4 1 3 2
5 4 1 3 2

Sample Output 3

0

A may equal B before doing any operation.


Sample Input 4

6
8 5 4 7 4 5
10 5 6 7 4 1

Sample Output 4

7



给出两个数组,每个数组有 n 个数,可以进行如下操作 :
将 a 数组中的 a[i]->a[i]+1 与 a[i+1]->a[i+1]-1 然后再交换位置,问最少需要多少次操作可以将 a 数组变为 b 数组




先看一下第 4 组样例该怎么做,

\[8,5,4,7,4,5 \]

想让第一个数变为 10,我们可以让 7 移动到第一个位置上来,也可以让最后一个 5 移动到第一个位置上来,但是就这一步而言让 7 过来是最优的,而 7 前面的 8 5 4,分别要减去 1;
所以现在的思路有了,对于 b 数组中的每一个位置 j,我们只要找到 a 数组中 \(a[i]+i-j=b[j]\) 的第一个 \(a[i]\) 即可,时间复杂度 \(O(n^2)\)

这样是远远不够的,我们需要更快速地方法,我们将上式做一个变化

\[a[i]+i=b[j]+j \]

这个式子就很漂亮,这样将 a 和 b 数组同时变为 \((a[i]+i)\)
\((b[i]+i)\) 的形式,这样 a ,b 数组就分别变为了

\[9 ,7 ,7 ,11 ,9 ,11 \]

\[11,7,9,11,9,7 \]

这个问题,两个数组相同,求交换多少次可以变成另一个数组,这不就是求 ‘逆序对’ 吗


const int N = 3e5 + 5;

    ll n, m, _;
    int i, j, k;
    int a[N];
    int b[N], c[N];
    map<int, vector<int>> mp;

void add(int x)
{
    for(; x <= n; x += lowbit(x)){
        c[x] ++;
    }
}

int ask(int x)
{
    int ans = 0;
    for(; x; x -= lowbit(x)){
        ans += c[x];
    }
    return ans;
}

signed main()
{
    //IOS;
    while(~ sd(n)){
        rep(i, 1, n) sd(a[i]);
        rep(i, 1, n) sd(b[i]);
        ll ok = 0;
        per(i, 1, n){
            a[i] += i;
            b[i] += i;
            mp[b[i]].pb(i);
            ok += a[i] - b[i];
        }
        rep(i, 1, n){
            int tmp = a[i];
            if(mp[a[i]].empty()){
                ok = 1;
                break;
            }
            a[i] = *mp[a[i]].rbegin();
            mp[tmp].pop_back();
        }
        if(ok){
            puts("-1");
            break;
        }
        ll ans = 0;
        per(i, 1, n){
            ans += ask(a[i]);
            add(a[i]);
        }
        pll(ans);
    }
    return 0;
}

posted @ 2021-07-09 18:55  Bcoi  阅读(71)  评论(0)    收藏  举报