← Static tasks

372. Super Pow

leetcode medium

#array#csharp#leetcode#math#medium#queue

Task

Ваша задача — вычислить а^b mod 1337, где a - положительное число, а b - чрезвычайно большое положительное целое число, заданное в виде массива.

Пример:

Input: a = 2, b = [3]

Output: 8

C# solution

matched/original
public class Solution {
    public int GetSum(int a, int b) {
        int x = System.Math.Abs(a), y = System.Math.Abs(b);
        if (x < y) return GetSum(b, a);
        int sign = a > 0 ? 1 : -1;
        if (a * b >= 0) {
            while (y != 0) {
                int carry = (x & y) << 1;
                x ^= y;
                y = carry;
            }
        } else {
            while (y != 0) {
                int borrow = ((~x) & y) << 1;
                x ^= y;
                y = borrow;
            }
        }
        return x * sign;
    }
}

C++ solution

auto-draft, review before submit
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
    public int GetSum(int a, int b) {
        int x = System.abs(a), y = System.abs(b);
        if (x < y) return GetSum(b, a);
        int sign = a > 0 ? 1 : -1;
        if (a * b >= 0) {
            while (y != 0) {
                int carry = (x & y) << 1;
                x ^= y;
                y = carry;
            }
        } else {
            while (y != 0) {
                int borrow = ((~x) & y) << 1;
                x ^= y;
                y = borrow;
            }
        }
        return x * sign;
    }
}

Java solution

matched/original
public class Solution {
    public int getSum(int a, int b) {
        int x = Math.abs(a), y = Math.abs(b);
        if (x < y) return getSum(b, a);
        int sign = a > 0 ? 1 : -1;

        if (a * b >= 0) {
            while (y != 0) {
                int carry = (x & y) << 1;
                x ^= y;
                y = carry;
            }
        } else {
            while (y != 0) {
                int borrow = ((~x) & y) << 1;
                x ^= y;
                y = borrow;
            }
        }
        return x * sign;
    }
}

JavaScript solution

matched/original
class Solution {
    getSum(a, b) {
        let x = Math.abs(a), y = Math.abs(b);
        if (x < y) return this.getSum(b, a);
        const sign = a > 0 ? 1 : -1;

        if (a * b >= 0) {
            while (y !== 0) {
                const carry = (x & y) << 1;
                x ^= y;
                y = carry;
            }
        } else {
            while (y !== 0) {
                const borrow = ((~x) & y) << 1;
                x ^= y;
                y = borrow;
            }
        }
        return x * sign;
    }
}

Python solution

matched/original
class Solution:
    def superPow(self, a: int, b: List[int]) -> int:
        MOD = 1337
        
        def powmod(x, y, mod):
            result = 1
            x = x % mod
            while y > 0:
                if y % 2 == 1:
                    result = (result * x) % mod
                y = y // 2
                x = (x * x) % mod
            return result
        
        def superPowHelper(a, b, mod):
            if not b:
                return 1
            last_digit = b.pop()
            part1 = powmod(a, last_digit, mod)
            part2 = powmod(superPowHelper(a, b, mod), 10, mod)
            return (part1 * part2) % mod
        
        return superPowHelper(a, b, MOD)

Go solution

matched/original
package main

import "math"

func getSum(a int, b int) int {
    x, y := int(math.Abs(float64(a))), int(math.Abs(float64(b)))
    if x < y {
        return getSum(b, a)
    }
    sign := 1
    if a < 0 {
        sign = -1
    }

    if a * b >= 0 {
        for y != 0 {
            carry := (x & y) << 1
            x ^= y
            y = carry
        }
    } else {
        for y != 0 {
            borrow := ((^x) & y) << 1
            x ^= y
            y = borrow
        }
    }
    return x * sign
}

Explanation

Algorithm

Разделите задачу на более мелкие задачи: вычислите a^b mod 1337, используя свойства модульной арифметики и степенной функции. Разделите большой показатель b на меньшие части, чтобы обрабатывать их по очереди.

Используйте метод быстрого возведения в степень (pow) для эффективного вычисления больших степеней с модулем 1337.

Объедините результаты для каждой части показателя b, используя свойства модульной арифметики: (a^b) % 1337 = ((a^(b1)) % 1337 * (a^(b2)) % 1337 * ...) % 1337.

😎