该程序的模运算步骤

时间:2015-05-13 13:19:03

标签: c modulus

我已在Thread中编写此代码,其中public static void main(String args[]) { RunnableA a1=new RunnableA(); new Thread(a1).start(); } 均为C。但根据问题的规范,a,b,cc,ma,mb,mcc,N,kint可能与N一样大。 k可以存储在我的计算机中的10^9变量中。但10^9的内部和最终价值对于inta,b,cc,ma,mb,mcc的较大值而言会更大,即使在N变量中也无法存储。

现在,我想在代码中看到k的打印值。我知道,unsigned long long int循环体操作中的一些聪明的模运算技巧可以创建正确的输出而不会出现任何溢出,也可以使程序时间有效。作为模运算的新手,我没能解决这个问题。有人能指出我的步骤吗?

mcc % 1000000007

我的尝试:

我使用for作为ma=1;mb=0;mcc=0; for(i=1; i<=N; ++i){ a=ma;b=mb;cc=mcc; ma = k*a + 1; mb = k*b + k*(k-1)*a*a; mcc = k*cc + k*(k-1)*a*(3*b+(k-2)*a*a); } printf("%d\n",mcc%1000000007); 并完成了此操作。它可以更优化??

a,b,cc,ma,mb,mcc

2 个答案:

答案 0 :(得分:2)

让我们看一个小例子:

mb = (k*b + k*(k-1)*a*a)%MOD;

此处,k*bk*(k-1)*a*a可能会溢出,总和也会出现问题

(x + y) mod m = (x mod m + y mod m) mod m

我们可以重写此内容(x= k*by=k*(k-1)*a*am=MOD

mb = ((k*b) % MOD + (k*(k-1)*a*a) %MOD) % MOD

现在,我们可以更进一步。从那以后

x * y mod m = (x mod m * y mod m) mod m

我们也可以使用k*(k-1)*a*a % MODx=k*(k-1)将乘法y=a*a重写为

((k*(k-1)) %MOD) * ((a*a) %MOD)) % MOD

我相信你可以做其余的事。虽然你可以在所有地方撒上% MOD,但是你应该仔细考虑是否需要它,考虑John's hint

  

添加两个n位数字会产生多达n + 1个数字,并且   将n位数乘以m位数会产生结果   最多n + m位数。

因此,有些地方你需要使用模数属性,有些地方你肯定不需要它,但这是你工作的一部分;)。

答案 1 :(得分:0)

在这些方面构建模板类是一个很好的练习:

template <int N>
class modulo_int_t
{
public:
    modulo_int_t(int value) : value_(value % N) {}
    modulo_int_t<N> operator+(const modulo_int_t<N> &rhs)
    {
        return modulo_int_t<N>(value_ + rhs.value) ;
    }
    // fill in the other operations
private:
    int value_ ;
} ;

然后使用modulo_int_t&lt; 1000000007&gt;编写操作。对象而不是int。 免责声明:在适当情况下长时间使用,并注意负面差异...