ARC-129-D- -1+2-1

-1+2-1

这一看以为是贪心推了半天最后发现是数学题(悲)

题目

给你一个长度为n的序列A,A = ( A 1 , A 2 , A 3 . . . A n A_1,A_2,A_3...A_n A1,A2,A3...An)
你可以反复的进行如下操作:选择一个 i i i,然后让 A i A_i Ai加上 2 2 2 , A i − 1 A_{i-1} Ai1 减去 1 1 1 A i + 1 A_{i+1} Ai+1 减去 1 1 1 。注意该序列是循环的,也就是操作 A 0 A_0 A0 等同于操作 A n A_n An,操作 A n + 1 A_{n+1} An+1 等同与操作 A 1 A_1 A1

如果通过这样的操作可以将A序列全部变为0的话,请你输出最小步数,如果不可以的话,输出-1。

Input

第一行一个正整数 n n n 3 ≤ n ≤ 200000 3 \le n \le 200000 3n200000
第二行n个正整数,第i个数代表 A i A_i Ai − 100 ≤ A i ≤ 100 -100 \le A_i \le 100 100Ai100

Output

输出一行一个正整数,最小步数或者-1。

Samples

4
3 0 -1 -2
5

对于样例,可以操作 2 3 3 4 4可以使数组变为全0

思路

  1. 显而易见, − 1 + 2 − 1 = 0 -1+2-1=0 1+21=0 ,意味着每一次操作不会改变原数组的总和,则:

特判 1 : ∑ A i = 0 \sum{A_i}=0 Ai=0

  1. f i f_i fi 为对第 i i i 个数字的修改次数,求 ∑ f i \sum{f_i} fi ,则有:

2 ∗ f i − f i − 1 − f i + 1 = − A i 2*f_i-f_{i-1}-f_{i+1}=-A_i 2fifi1fi+1=Ai

  1. 通过移项可得:

( f i + 1 − f i ) − ( f i − f i − 1 ) = A i (f_{i+1}-f_i)-(f_i-f_{i-1})=A_i (fi+1fi)(fifi1)=Ai

  1. B i = f i + 1 − f i B_i=f_{i+1}-f_i Bi=fi+1fi , 3 3 3 式转化为:

B i − B i − 1 = A i B_i-B_{i-1}=A_i BiBi1=Ai

  1. 4 4 4 式 对 A i A_i Ai 累加推的:

B i = ∑ j = 1 i A j + B 1 − A 1 B_i=\sum_{j=1}^{i}A_j+B_1-A_1 Bi=j=1iAj+B1A1

  1. 5 5 5 式 对 B i B_i Bi 累加推的:

∑ i = 1 n B i = n ∗ ( B 1 − A 1 ) + i ∗ ∑ j = 1 i A i \sum_{i=1}^nB_i=n*(B_1-A_1)+i * \sum_{j=1}^iA_i i=1nBi=n(B1A1)+ij=1iAi

  1. 化简 6 6 6 式:

∑ i = 1 n B i = n ∗ B 1 − ∑ j = 2 n ( n + 1 − j ) ∗ A j \sum_{i=1}^nB_i=n*B_1-\sum_{j=2}^n(n+1-j)*A_j i=1nBi=nB1j=2n(n+1j)Aj

  1. 累加可得:

∑ i = 1 n B i = f n + 1 − f 1 = 0 \sum_{i=1}^nB_i=f_{n+1}-f_1=0 i=1nBi=fn+1f1=0

  1. 7 7 7 式 移项得:

B i = ∑ i = 2 n ( n + 1 − i ) ∗ A i n = ∑ j = 1 i A j + B 1 − A 1 B_i=\frac{\sum_{i=2}^n(n+1-i)*A_i}{n}=\sum_{j=1}^{i}A_j+B_1-A_1 Bi=ni=2n(n+1i)Ai=j=1iAj+B1A1

通过数组 f f f 的定义,由于 f i f_i fi 是第 i i i 个数的操作次数,又因为我们需要总操作次数最小。

因此我们要找到一个数 x x x ,令 f x = 0 f_x=0 fx=0 ,实际上对于每个 i i i ,答案最小为 f i − f x f_i-f_x fifx

总答案为 ∑ i = 1 n f i − n ∗ f x \sum_{i=1}^nf_i-n*f_x i=1nfinfx

C i = f i − f x C_i=f_i-f_x Ci=fifx

为了方便计算,我们令 x x x 的初值为1,因此

对于 i = 0 , C 1 = 0 i=0,C_1=0 i=0,C1=0,对于 i > = 2 , C i = C i − 1 + B i − 1 i>=2,C_i=C_{i-1}+B_{i-1} i>=2,Ci=Ci1+Bi1

因此要找到一个 x x x 满足 ∑ i = 1 n f i − n ∗ f x \sum_{i=1}^nf_i-n*f_x i=1nfinfx 最小

即 找到最小的 C i C_i Ci 为minn,对于每个 C i − = m i n n C_i-=minn Ci=minn

再将 c i c_i ci 求和就为答案 ∑ i = 1 n f i − n ∗ f x \sum_{i=1}^nf_i-n*f_x i=1nfinfx

#include <iostream>
using namespace std;
#define int long long

int sum, n, a[2000005], m, x, s;
signed main()
{
    
    
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
    
    
        cin >> a[i];
        a[i] += a[i - 1]; //算前缀和
        sum += a[i];
    }

    if (a[n] != 0) //显然,-1+2-1=0,操作前后的总和不变,则总和不为0则不能操作
    {
    
    
        cout << "-1" << endl;
        return 0;
    }

    for (int i = 1; i <= n; i++) //不难发现,操作与顺序无关,只与各位置操作次数有关
    {
    
    
        if (sum % n)
        {
    
    
            cout << "-1";
            return 0;
        }
        s += sum / n - a[i];
        m = max(m, s);
        x += s;
    }
    cout << n * m - x << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/skyflying266/article/details/126520792