📌  相关文章
📜  找到最大范围[L,R],其和可被M整除

📅  最后修改于: 2021-05-06 23:47:11             🧑  作者: Mango

给定一个由正数组成的数组arr [] ,任务是找到其和可被M整除的最大范围[L,R]。如果不存在范围,则返回-1。

例子:

幼稚的方法:幼稚的方法是我们可以遍历数组中所有可能的L和R并检查和是否可整。如果是,则存储数组的长度。

高效的方法:这里的想法是使用前缀和数组。

  • 最初,将计算值的前缀和。
  • 一旦计算出前缀总和,就将每个值替换为取模M的值。
  • 最终值相等的索引是和被M完全整除的范围。
  • 找到相同值的最大范围。

下面是上述方法的实现,

// C++ implementation of the above approach.
#include 
using namespace std;
  
// Function to find the maximum range
// whose sum is divisible by M.
pair maxrange(int n,
                        int a[], int m)
{
    int pre[n + 5];
    map > mpp;
    int value, l, r, lans = -1,
                     rans = -1, ans = 0;
  
    // Calculate the prefix sum
    pre[0] = a[0];
    for (int i = 1; i < n; i++) {
        pre[i] = a[i] + pre[i - 1];
    }
  
    // Replacing the values with modulo M
    // and inserting the indices into the map
    for (int i = 0; i < n; i++) {
        pre[i] = pre[i] % m;
        mpp[pre[i]].insert(i);
    }
  
    // Calculate the range [L, R]
    for (auto it = mpp.begin(); it != mpp.end(); it++) {
        if (it->first == 0) {
            value = *((it->second).rbegin()) + 1;
            l = 1;
            r = value;
        }
        else {
            value = *((it->second).rbegin())
                    - *((it->second.begin()));
            l = *((it->second.begin())) + 2;
            r = *((it->second).rbegin()) + 1;
        }
        if (value > ans && l <= r) {
            ans = value;
            lans = l;
            rans = r;
        }
    }
  
    return make_pair(lans, rans);
}
  
// Driver code
int main()
{
    int A[] = { 3, 7, 5, 2, 5, 10 };
    int N = sizeof(A) / sizeof(A[0]);
    int M = 3;
    pair value = maxrange(N, A, M);
    if (value.first == -1) {
        cout << -1 << "\n";
    }
    else {
        cout << value.first << " "
             << value.second << "\n";
    }
    return 0;
}
输出:
1 3