简体   繁体   中英

How to generate n number of ones in java?

I am stuck with an algorithm where i need to generate n number of figures '1', where n<=10^16 and n>=1 . I successfully generated n number of ones in a for loop with BigInteger because long as well as string are failed to hold this. But the problem is the time limit of this is 4 sec and it takes more than 4 sec for n>10^5 . This is clearly generating in O(n) . I think corresponding code is not necessary. I find many websites but can not find any solution. Any better algorithm would be helpful. Thanks.
EDIT: it is a puzzle question where n and m are input and i need to print 111...(n times) mod m where limits are 1≤N≤10^16 and 2≤M≤10^9 . For example,
Suppose n=3 & m=3 then print 111%3 which is equal to 0
Suppose n=5 & m=18 then print 11111%18 which is equal to 5 .
If you use long or String then a NumberFormatException is thrown then i change it to BigInteger then exception is gone.

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));
}

在此输入图像描述

If S(n) is n ones, then these equations hold:

S(1) = 1
S(2n) = S(n) * (10^n + 1)
S(n+1) = S(n) * 10 + 1

You can use these two recurrences (modulo m) to compute S(n) modulo m.

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]

You still need to be able to compute 10^n % m efficiently, and while this can be done using exponentiation by squaring, one can also use the fact that 10^n = 9*S(n)+1.

Using this latter relation between 10^n and S(n), one gets to this set of equations which are easily coded up as a recursive (or iterative) program:

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]

In Python this gives a run-time for n=10^16, m=10^9 of 0.017s on my laptop, which is well within the 4s deadline.

I have a thought that might help you in some way optimising your code.

The following is my direct translation of my maths notes (with comments in italic font), so if you find something unclear, please point it out.

How to find if number is divisible by 37 (in your case it is m)

We have following

10^0 ≡ 1 (mod 37)
10^1 ≡ 10 (mod 37)
10^2 ≡ 26 (mod 37)
10^3 ≡ 1 (mod 37)

basically do this until you see repetition

So now if we want to see if number is divisible by 37 (or what is leftover) we substitute the powers of 10 with coefficients we got above. This means that a*10^3 + b*10^2 + c*10^1 + d mod 37 = a*1 + b*26 + c*10 + d mod 37.

An example with real number

(a number with 10^16 digits 1 ) mod 37 = (1 + 26 + 10 + 1) * 10^16 / 4 mod 37 = 21

you can repeat this process more then once, every time you do this the resultant number is shrinking proportionally (number with 10^16 digits shrank to a number with 16 digits)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM