我试图在SPOJ上解决这个问题(http://www.spoj.pl/problems/REC/)
F(n) = a*F(n-1) + b
我们必须找到F(n) Mod (m)
0 <= a, b, n <= 10^100
1 <= M <= 100000
F(0)=1
我正在尝试用JAVA中的BigInteger来解决它,但是如果我从0到n运行一个循环来获取TLE。我怎么能解决这个问题?任何人都可以给出一些暗示吗?不要发布解决方案。我想要提示如何有效地解决它。
答案 0 :(得分:1)
注意,残基mod(m)的模式应该具有线性递归的重复模式,并且通过鸽子原理具有长度<= m。您只需要计算前m个条目,然后找出哪些条目将应用于F(n)以获得n的实际值。
它还有助于解决更简单的问题。让我们选择非常小的值,比如a = 2,b = 1,m = 5,n = 1000。
注意残留物是[1,3,2,0,1,3 ......],它们将永远重复。那么从这个例子中,你如何确定F(1000)Mod 5而没有一直循环到第1000个条目?
答案 1 :(得分:0)
首先,我会告诉你如何解决一个更简单的问题。假设b为零。然后你只需要计算一个 n mod M.而不是乘以n-1次,使用分而治之的技术:
// Requires n >= 0 and M > 0.
int modularPower(int a, int n, int M) {
if (n == 0)
return 1;
int result = modularPower(a, n / 2, M);
result = (result * result) % M;
if (n % 2 != 0)
result = (result * a) % M;
return result;
}
所以你可以用 floor(n / 2)来计算 n ,然后将其平方,如果n是奇数,则再乘以a。
要解决您的问题,首先定义函数f(x)=(a x + b)(mod M)。你需要计算f n (1),这是对初始值1应用f n次。所以你可以像上一个问题一样使用分而治之。幸运的是,两个线性函数的组合也是线性的。您可以通过三个整数(两个常数和模数)表示线性函数。编写一个带有线性函数和指数的函数,并返回多次组合的函数。