4

problem description

I got this question yesterday in a challenge. I thought I had coded it correctly and my sample test case was passed. However not even a single test case passed at the backend. Here is my code. Please, someone, help me out. The challenge is over for me and so I can't submit it further. But I want to learn from my mistakes. Thanks.

  import java.io.*;
//import java.util.*;


public class TestClass {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter wr = new PrintWriter(System.out);
         int n = Integer.parseInt(br.readLine().trim());
         String[] arr_a = br.readLine().split(" ");
         int[] a = new int[n];
         for(int i_a=0; i_a<arr_a.length; i_a++)
         {
            a[i_a] = Integer.parseInt(arr_a[i_a]);
         }

         long out_ = solve(a);
         System.out.println(out_);

         wr.close();
         br.close();
    }
    static long solve(int[] a){
        // Write your code here
        long sum = 0l;
        long MAX = 10000000011l;
        long i = 1l;
        for(int x : a) {
            long count = 0;
            while(x>0) {
                x &= (x-1l);
                count++;
            }
            long res = 1l;
            long temp = i;
            count = count % MAX;
            while(temp > 0) {
                if((temp & 1l) == 1l) {
                    res = (res * count) % MAX;
                }
                temp = temp >> 1l;
                count = ((count % MAX) * (count % MAX)) % MAX;

            }

            long t =((sum%MAX) + (res % MAX))%MAX;
            sum = t;
            i++;
        }

        return sum;
    }
}
user0042
  • 7,917
  • 3
  • 24
  • 39
Brij Raj Kishore
  • 1,595
  • 1
  • 11
  • 24

1 Answers1

1

It is a bit strange that "not even a single test case passed", but the only error I see is your exponentiation by squaring part.

All your numbers are less than 10^10 + 11, but this constant has more than 32 bits, and when you multiply, you get an overflow sometimes (because long is a 64-bit signed integer).

This can be fixed by several approaches:

  1. (a*b) % M operation can be done with the algorithm that is similar to your "exponentiation by squaring" implementation. You just need to replace all multiplications with additions. As a result, multiplication is replaced with O(log(n)) additions and 'multiplying by 2' operations. Sample implementation:

    static long multiply(long a, long b, long M) {
        long res = 0;
        long d = a % M;
    
        while (b > 0) {
            if ((b & 1) == 1) {
                res = (res + d) % M;
            }
    
            b >>= 1;
            d = (d + d) % M;
        }
        return res;
    }
    
  2. You can just cache b^i % M numbers for previously computed steps. For every number of set bits (there are not so many of them), you can save previously computed values and last(b) - the last i when a[i] had b set bits. Then just compute the new value with a linear loop from last(b) + 1 till current index i.

  3. Use BigInteger for multiplications.

DAle
  • 8,990
  • 2
  • 26
  • 45
  • [Dale](https://stackoverflow.com/users/4759200/dale) I got your point but now while implementing your method in f(n) = 0^0 + 1^1 + 2^2 .... + n ^ n . f(n) mod m where n <= 10^9 & m <= 10 ^ 3. I am getting time limit exceeded. Help. – Brij Raj Kishore Jul 19 '17 at 06:06
  • @BrijRajKishore, you need this method when you're multiplying numbers that are bigger than `2^31` (as in the question above). If you have `n <= 10^9`, you don't need it. – DAle Jul 19 '17 at 07:33
  • [Dale](https://stackoverflow.com/users/4759200/dale) I have tried above method with or without your multiply method as well as used BigInteger for the question f(n) % m. where f(n) = 0^0 + 1^1 + 2^2 .... but all I got is TLE. Why? isn't this the fast algo? Please help me out. – Brij Raj Kishore Jul 20 '17 at 19:01
  • @BrijRajKishore, this is a completely different task, why don't you create a new question? I believe you don't need any approaches from my answer to solve this task. And take attention to the fact that `m` is relatively small. – DAle Jul 21 '17 at 06:44