• + 1 comment
    
    

    public static long summingPieces(List arr) { long mod = 1000000007; int len = arr.size();

        // Base Cases
        if (len == 1) {
            return arr.get(0) % mod;
        }
        if (len == 2) {
            long totalVal = arr.get(0) + arr.get(1);
            totalVal += 2 * (arr.get(0) + arr.get(1));
            return totalVal % mod;
        }
    
        // Precompute powers of 2
        long[] powersOf2 = new long[len + 1];
        powersOf2[0] = 1;
        for (int i = 1; i <= len; i++) {
            powersOf2[i] = (powersOf2[i - 1] * 2) % mod;
        }
    
        // Initialization
        int pointer1 = 0;
        int pointer2 = len - 1;
        long multiplier = powersOf2[len] - 1;
    
        // Find first difference To next multipler
        int difPower1 = len - 2;
        int difPower2 = 0;
        long totalVal = 0;
        while (true) {
            int topElem = arr.get(pointer1);
            int bottomElem = arr.get(pointer2);
    
            // Calculate and update totalVal
            totalVal = (totalVal + (multiplier * topElem % mod)) % mod;
            if (pointer1 != pointer2) {
                totalVal = (totalVal + (multiplier * bottomElem % mod)) % mod;
            }
    
            if (pointer1 == pointer2 || pointer1 == pointer2 - 1) {
                break;
            }
    
            // Compute difference to next multipler, and update next multiplier
            long currentDifference = (powersOf2[difPower1] - powersOf2[difPower2] + mod) % mod;
            multiplier = (multiplier + currentDifference) % mod;
    
            // Increment difference powers and pointers
            difPower1--;
            difPower2++;
            pointer1++;
            pointer2--;
        }
    
        return totalVal % mod;
    }
    

    }