长度分割算法c ++问题的倍数

问题描述

问题陈述

您会得到一个由 n 个整数组成的数组 a

您想通过精确执行三遍以下操作来使 a 的所有元素等于零:

选择一个段,对于该段中的每个数字,我们可以为其添加一个 len 的倍数,其中 len 是该段的长度(添加的整数可以为不同)。

可以证明,始终可以使所有元素等于零。

输入 第一行包含一个整数 n (1≤ n ≤100000):数组元素的数量。

第二行包含以空格分隔的数组 a n 个元素: a1 a2 ,… , an (− 10 ^ 9≤ ai ≤10 ^ 9)。

输出 输出应包含代表三项操作的六行。

对于每个操作,打印两行:

第一行包含两个整数 l r (1≤ l r n ):选定线段的边界。 第二行包含 r - l +1个整数 bl bl + 1,…, br (−10 ^ 18≤ bi ≤10 ^ 18):要添加到 al al +1,...的数字, ar ; bi应该被 r l +1整除。

示例

输入

4

1 3 2 4

输出

1 1

-1

3 4

4 2

2 4

-3 -6 -6

代码解决方案

#include<bits/stdc++.h>
 
int64_t minv(int64_t a,int64_t m) {
    assert(0 < a && a < m);
    if (a == 1) return 1;
    return m - minv(m % a,a) * m / a;
}
 
int main() {
    using namespace std;
    ios_base::sync_with_stdio(false),cin.tie(nullptr);
 
    int N; cin >> N;
    vector<int64_t> A(N);
    for (int i = 0; i < N; i++) {
        cin >> A[i];
    }
 
    if (N == 1) {
        cout << 1 << ' ' << 1 << '\n' << -A[0] << '\n';
        cout << 1 << ' ' << 1 << '\n' << 0 << '\n';
        cout << 1 << ' ' << 1 << '\n' << 0 << '\n';
        exit(0);
    }
 
    int64_t invNm1 = minv(N-1,N);
    assert(invNm1 * (N-1) % N == 1);
 
    vector<int64_t> op1(N);
    vector<int64_t> op2(N-1);
    for (int i = 0; i < N-1; i++) {
        op2[i] = -A[i] % N * invNm1 % N;
        assert((A[i] + (op2[i] * (N-1))) % N == 0);
        op1[i] = -(A[i] + (op2[i] * (N-1))) / N;
        assert(A[i] + (op1[i] * N) + (op2[i] * (N-1)) == 0);
    }
 
    cout << 1 << ' ' << N << '\n';
    for (int i = 0; i < N; i++) {
        cout << op1[i] * N << " \n"[i+1==N];
    }
    cout << 1 << ' ' << N-1 << '\n';
    for (int i = 0; i < N-1; i++) {
        cout << op2[i] * (N-1) << " \n"[i+1==N-1];
    }
 
    cout << N << ' ' << N << '\n';
    cout << -A[N-1] << '\n';
 
    return 0;
}

问题

我相信代码对minv使用了扩展的欧几里得算法,我确实需要帮助来可视化minv部分的情况。另外,我在遵循op2和op1方程的for循环中的逻辑以及代码如何从提供的输入中产生输出时遇到麻烦。有人在这里与方程式和逻辑分享对代码的解释吗?

解决方法

minv函数可找到模乘逆。意思是,对于给定的数字a,其反模N是满足b的数字a*b % N = 1

Extended Euclidian algorithm can be used to find such inverse.

至:

cout << op1[i] * N << " \n"[i+1==N];

这只是索引的骗局。 "<space>\n"的类型为 char[2] char[3],因此可以使用索引在空格和换行符之间进行选择。由于布尔可以隐式转换为int-true->1false->0,因此布尔可用于为此类数组建立索引。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...