N^2公式的快速模块

Fast Modulo for N^2 formula

本文关键字:模块      更新时间:2023-10-16

我有一个问题,当我试图分辨出此ecuation时,

(1*1 2*2 ... n*n)%10234573

我在C 中的解决方案,

#include <iostream>
#include <cmath>
using namespace std;
int main()
{
    unsigned long long int n, s= 0;
    cin >> n;
    if (n%10234573 == 0)
    {
        cout << 0;
    }
    else
    {
        cout << n*(n+1)*((2*n+1))/6 % 10234573;
    }
    return 0;
}

我需要一个更大的数字的解决方案,即10^9 一个快速。

要处理更大的数字问题,我们需要以更有效的方式使用数字10234573

我们知道,对于mod,我们有:

(m*n) mod x = ((m mod x)*(n mod x)) mod x

在我们的计算中使用上述公式:

n*(n+1)*((2*n+1))/6 % 10234573

我们需要摆脱dividing by 6

我们知道要将数字除以6,我们需要将其分为2和3。

所以我们有

unsigned long long int mod = 10234573;
unsigned long long int data[3] = {n, n + 1, 2*n + 1};
bool dividedByTwo = false;
bool dividedByThree = false;
for(int i = 0; i < 3; i++){
    if(data[i] % 2 == 0 && !dividedByTwo){
       data[i]/=2;
       dividedByTwo = true; 
    }
    if(data[i] % 3 == 0 && !dividedByThree){
       data[i]/=3;
       dividedByThree = true; 
    }
}
//Finally, applying mod to our formula
cout<< ((((data[0]%mod)*(data[1]%mod))%mod)*(data[2]%mod))%mod;

您应该在乘法上使用模量的分布属性,因此您不会溢出。

(ab) % p = ((a%p) (b%p)) %p

对于3个数字,您得到(使用上述公式)

(abc) % p = ((ab) c) % p = ((((a%p) (b%p)) %p) (c%p)) %p

因此,不要先进行3个数字的乘法,然后是模量,而是取每个数字的模量,然后乘以乘法,然后在末端再次取模。