简体   繁体   English

倍数除法算法c++题

[英]Multiples of length division algorithm c++ question

Problem Statement问题陈述

You are given an array a of n integers.给定一个n 个整数组成的数组a

You want to make all elements of a equal to zero by doing the following operation exactly three times:你想通过执行以下操作准确三次作出相同的所有元素为零:

Select a segment, for each number in this segment we can add a multiple of len to it, where len is the length of this segment (added integers can be different).选择一个segment,对于这个segment中的每个数字,我们可以给它加上len的倍数,其中len就是这个segment的长度(相加的整数可以不同)。

It can be proven that it is always possible to make all elements of a equal to zero.可以证明,总是可以使 a 的所有元素都为零。

Input The first line contains one integer n (1 ≤ n ≤ 100000): the number of elements of the array.输入 第一行包含一个整数n (1 ≤ n ≤ 100000):数组的元素数。

The second line contains n elements of an array a separated by spaces: a1 , a2 ,…, an (−10^9 ≤ ai ≤ 10^9).第二行包含由空格分隔的数组a 的n 个元素: a1 , a2 ,..., an (−10^9 ≤ ai ≤ 10^9)。

Output The output should contain six lines representing three operations.输出 输出应包含代表三个操作的六行。

For each operation, print two lines:对于每个操作,打印两行:

The first line contains two integers l , r (1 ≤ lrn ): the bounds of the selected segment.第一行包含两个整数l , r (1 ≤ lrn ):所选段的边界。 The second line contains rl +1 integers bl , bl +1,…, br (−10^18 ≤ bi ≤ 10^18): the numbers to add to al , al +1,…, ar , respectively;第二行包含rl +1 个整数bl , bl +1,..., br (−10^18 ≤ bi ≤ 10^18):分别与al , al +1,..., ar相加的数; bi should be divisible by rl +1. bi 应该可以被rl +1 整除。

Example例子

input输入

4 4

1 3 2 4 1 3 2 4

output输出

1 1 1 1

-1 -1

3 4 3 4

4 2 4 2

2 4 2 4

-3 -6 -6 -3 -6 -6

Code Solution代码解决方案

#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;
}

Question

I believe the code is using an extended euclidean algorithm for minv, and I really need help to visualize what's going on with the minv part.我相信代码对 minv 使用了扩展的欧几里得算法,我真的需要帮助来可视化 minv 部分的情况。 Also, I'm having trouble following the logic inside the for loop with the op2 and op1 equations and how the code produces the output from the input provided.此外,我在遵循带有 op2 和 op1 方程的 for 循环内部的逻辑以及代码如何从提供的输入生成输出时遇到问题。 Would anyone please share explanations to the code with the equations and logic here?任何人都可以在这里分享对带有方程式和逻辑的代码的解释吗?

minv function finds modular multiplicative inverse. minv函数找到模乘逆。 Meaning, for a given number a , its inverse modulo N is a number b which satisfies a*b % N = 1 .意思是,对于给定的数字a ,其逆模N是满足a*b % N = 1的数字b

Extended Euclidian algorithm can be used to find such inverse. 可以使用扩展欧几里得算法来找到这样的逆。

As for:至于:

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

This is just index trickery with bools.这只是布尔值的索引技巧。 "<space>\\n" has a type char[2] char[3] , thus indices can be used to select between a space and a newline. "<space>\\n"具有 char[2] char[3] ,因此索引可用于在空格和换行符之间进行选择。 Bool can be used to index such array since bools are implicitly convertible to int s - true->1 , false->0 . Bool 可用于索引此类数组,因为 bool 可以隐式转换为int s - true->1false->0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM