我遇到了一个算法,我需要生成n个数字'1',其中n<=10^16
和n>=1
。我使用for loop
在BigInteger
中成功生成了n个,因为long
以及string
无法保留此值。但问题是时间限制为4 sec
,4 sec
需要的时间超过n>10^5
。这显然是在O(n)
中产生的。我认为没有必要使用相应的代码。我发现很多网站但找不到任何解决方案。任何更好的算法都会有所帮助。谢谢。
编辑:这是一个拼图问题,n
和m
输入,我需要打印111...(n times) mod m
,其中限制为1≤N≤10^16
和2≤M≤10^9
。例如,
假设n=3
&amp; m=3
然后打印111%3
,其等于0
。假设n=5
&amp; m=18
然后打印11111%18
,等于5
。
如果您使用long
或String
,则会抛出NumberFormatException
我将其更改为BigInteger
然后异常消失。
public static void main(String[] ar){
Scanner in= new Scanner(System.in);
int t=in.nextInt();
while(t-->0){
BigInteger n=new BigInteger(Long.toString(in.nextLong()));
BigInteger m=new BigInteger(Long.toString(in.nextLong()));
BigInteger s=new BigInteger("1");
for(long i=1;i<n.intValue();i++)
s = s.multiply(new BigInteger("10")).add(new BigInteger("1"));
System.out.println(s.mod(m));
}
答案 0 :(得分:5)
如果S(n)是n个,则这些方程式成立:
S(1) = 1
S(2n) = S(n) * (10^n + 1)
S(n+1) = S(n) * 10 + 1
您可以使用这两个重复(模m)来计算S(n)模数。
S(n) % m =
1 [if n is 1]
((S(n/2) % m) * ((10^{n/2} % m) + 1)) % m [if n is even]
((S(n-1) % m)) * 10 + 1) % m [if n is odd]
你仍然需要能够有效地计算10 ^ n%m,虽然这可以通过使用求幂进行平方来完成,但也可以使用10 ^ n = 9 * S(n)+1的事实。 / p>
使用10 ^ n和S(n)之间的后一种关系,可以得到这组方程式,这些方程式很容易编码为递归(或迭代)程序:
S(n) % m =
1 [if n is 1]
x*(9x+2) % m where x = S(n/2)%m [if n is even]
((S(n-1) % m) * 10 + 1) % m [if n is odd]
在Python中,这给我的笔记本电脑上的n = 10 ^ 16,m = 10 ^ 9,0.017s的运行时间,这完全在4s的最后期限内。
答案 1 :(得分:1)
我有一个想法,可以帮助您以某种方式优化您的代码。
以下是我的数学笔记的直接翻译(带有斜体字的注释),所以如果你发现不清楚的地方,请指出。
如何查找数字是否可被37 整除(在您的情况下为m)
我们有以下
10 ^0≡1(mod 37)
10 ^1≡10(mod 37)
10 ^2≡26(mod 37)
10 ^3≡1(mod 37)
基本上这样做,直到你看到重复
所以现在如果我们想看看数字是否可被37整除(或剩下的是什么),我们用上面得到的系数代替10的幂。这意味着 a * 10 ^ 3 + b * 10 ^ 2 + c * 10 ^ 1 + d mod 37 = a * 1 + b * 26 + c * 10 + d mod 37.
实数
的示例(数字为10 ^ 16位1
)mod 37 =(1 + 26 + 10 + 1)* 10 ^ 16/4 mod 37 = 21
您可以重复此过程一次,每次执行此操作时,结果数字按比例缩小(10 ^ 16位数字缩小为16位数字)