CSES - Aalto Competitive Programming 2024 - wk8 - Wed - Results
Submission details
Task:A TIMES B!
Sender:aalto2024i_004
Submission time:2024-10-30 17:48:52 +0200
Language:C++ (C++20)
Status:READY
Result:
Test results
testverdicttime
#1ACCEPTED0.00 sdetails
#2ACCEPTED0.00 sdetails
#3ACCEPTED0.00 sdetails
#4ACCEPTED0.00 sdetails
#5ACCEPTED0.00 sdetails
#60.00 sdetails
#70.00 sdetails
#80.00 sdetails
#90.00 sdetails
#100.00 sdetails
#11ACCEPTED0.00 sdetails
#12ACCEPTED0.00 sdetails
#13ACCEPTED0.00 sdetails
#140.00 sdetails
#150.00 sdetails
#16ACCEPTED0.00 sdetails
#17ACCEPTED0.00 sdetails
#180.00 sdetails
#190.00 sdetails
#20ACCEPTED0.01 sdetails
#21ACCEPTED0.00 sdetails
#220.00 sdetails
#230.00 sdetails
#240.00 sdetails
#25ACCEPTED0.00 sdetails
#260.00 sdetails
#27ACCEPTED0.00 sdetails
#28ACCEPTED0.00 sdetails
#290.00 sdetails
#300.00 sdetails
#310.01 sdetails
#320.01 sdetails
#330.00 sdetails
#340.01 sdetails
#350.01 sdetails
#360.01 sdetails
#370.01 sdetails
#380.01 sdetails
#390.01 sdetails
#40ACCEPTED0.01 sdetails
#410.01 sdetails
#420.01 sdetails
#430.01 sdetails
#440.01 sdetails
#450.01 sdetails
#460.02 sdetails
#470.80 sdetails
#480.83 sdetails
#490.12 sdetails
#500.60 sdetails
#510.18 sdetails
#520.80 sdetails
#530.81 sdetails
#540.07 sdetails
#550.80 sdetails
#56--details
#57--details
#58--details
#59--details
#60--details
#61--details
#62--details
#63--details
#64--details
#65--details

Compiler report

input/code.cpp: In function 'void schonhageStrassenMultiplication(std::string, std::string)':
input/code.cpp:929:4: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
  929 |    for (int i = 0; i < (n + m-1); i++)
      |    ^~~
input/code.cpp:931:7: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
  931 |       BigNumber p = a;
      |       ^~~~~~~~~

Code

#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()

#define BIGNUMBER_H

/**
 * BigNumber class
 */
class BigNumber {
public:
    //@{
    /**
     * BigNumber constructor
     * @param number - The initial value of the BigNumber
     */
    BigNumber(std::string number);
    BigNumber(long long number);
    //@}
    std::string _numberString;      //The big number represented as a string
    /**
     * Add another BigNumber to the current instance
     * @param other - The other BigNumber
     * @return The sum of the two BigNumbers
     */
    BigNumber add(BigNumber other);

    /**
     * Subtract another BigNumber from the current instance
     * @param other - The other BigNumber
     * @return The difference of the two BigNumbers
     */
    BigNumber subtract(BigNumber other);

    /**
     * Multiply the current instance by another BigNumber
     * @param other - The other BigNumber
     * @return The product of the two BigNumbers
     */
    BigNumber multiply(BigNumber other);

    /**
     * Divide the current instance by another BigNumber
     * @param other - The other BigNumber
     * @return The quotient of the two BigNumbers
     */
    BigNumber divide(BigNumber other);

    /**
     * Raise the current instance to the power of an exponent
     * @param exponent - The power to be raised by
     * @return - The resulting BigNumber after exponentiation
     */
    BigNumber pow(int exponent);

    /**
     * Get the string value of the current instance
     * @return The BigNumber as a string
     */
    std::string getString();

    /**
     * Set the value of the current instance with a string
     * @param newStr - The new value for the BigNumber
     * @return The BigNumber with the new value
     */
    BigNumber setString(const std::string &newStr);

    /**
     * Negates the current instance
     * @return The BigNumber after negation
     */
    BigNumber negate();

    BigNumber trimLeadingZeros();

    //@{
    /**
     * Check if another BigNumber is equal to the current instance
     * @param other - The other BigNumber
     * @return True if equal, otherwise false
     */
    bool equals(const BigNumber &other);
    bool equals(const long long &other);
    bool equals(const std::string &other);
    //@}

    /**
     * Get the number of digits in the current instance
     * @return The number of digits
     */
    unsigned int digits();

    /**
     * Get whether or not the current instance is a negative number
     * @return True if negative, otherwise false
     */
    bool isNegative() const;

    /**
     * Get whether or not the current instance is a positive number
     * @return True if positive, otherwise false
     */
    bool isPositive();

    /**
     * Get whether or not the current instance is an even number
     * @return True if even, otherwise false
     */
    bool isEven();

    /**
     * Get whether or not the current instance is an odd number
     * @return True if odd, otherwise false
     */
    bool isOdd();

    /**
     * Get the absolute value of the current instance
     * @return The absolute value of the BigNumber
     */
    BigNumber abs() const;

    /**
     * Output stream operator
     * @param os The output stream
     * @param num The current instance
     * @return The output stream with the current instance
     */
    friend std::ostream &operator<<(std::ostream &os, const BigNumber &num);

    //@{
    /**
     * Addition operator
     * @param b1 - The current instance
     * @param b2 - The number being added
     * @return The sum of the two numbers
     */
    friend BigNumber operator+(BigNumber b1, const BigNumber &b2);
    friend BigNumber operator+(BigNumber b1, const long long &b2);
    friend BigNumber operator+(BigNumber b1, const std::string &b2);
    //@}

    //@{
    /**
     * Subtraction operator
     * @param b1 - The current instance
     * @param b2 - The number being subtracted
     * @return The difference of the two numbers
     */
    friend BigNumber operator-(BigNumber b1, const BigNumber &b2);
    friend BigNumber operator-(BigNumber b1, const long long &b2);
    friend BigNumber operator-(BigNumber b1, const std::string &b2);
    //@}

    //@{
    /**
     * Multiplication operator
     * @param b1 - The current instance
     * @param b2 - The number being multiplied by
     * @return The product of the two numbers
     */
    friend BigNumber operator*(BigNumber b1, const BigNumber &b2);
    friend BigNumber operator*(BigNumber b1, const long long &b2);
    friend BigNumber operator*(BigNumber b1, const std::string &b2);
    //@}

    //@{
    /**
     * Division operator
     * @param b1 - The current instance
     * @param b2 - The number being divided by
     * @return The quotient of the two numbers
     */
    friend BigNumber operator/(BigNumber b1, const BigNumber &b2);
    friend BigNumber operator/(BigNumber b1, const long long &b2);
    friend BigNumber operator/(BigNumber b1, const std::string &b2);
    //@}

    /**
     * Exponent operator
     * @param b1 - The current instance
     * @param b2 - The exponent
     * @return The value after exponentiation
     */
    friend BigNumber operator^(BigNumber b1, const int &b2);

    //@{
    /**
     * Equality operator
     * @param b1 - The current instance
     * @param b2 - Another value
     * @return True if equal, otherwise false
     */
    friend bool operator==(BigNumber b1, const BigNumber &b2);
    friend bool operator==(BigNumber b1, const long long &b2);
    friend bool operator==(BigNumber b1, const std::string &b2);
    //@}

    /**
     * Greater-than operator
     * @param b1 - The current instance
     * @param b2 - Another BigNumber
     * @return True if current instance is greater, otherwise false
     */
    friend bool operator>(BigNumber b1, const BigNumber &b2);

    /**
     * Less-than operator
     * @param b1 - The current instance
     * @param b2 - Another BigNumber
     * @return True if current instance is less, otherwise false
     */
    friend bool operator<(BigNumber b1, const BigNumber &b2);

    /**
     * Greater-than or equal-to operator
     * @param b1 - The current instance
     * @param b2 - Another BigNumber
     * @return True if current instance is greater or equal, otherwise false
     */
    friend bool operator>=(BigNumber b1, const BigNumber &b2);

    /**
     * Less-than or equal-to operator
     * @param b1 - The current instance
     * @param b2 - Another BigNumber
     * @return True if current instance is less or equal, otherwise false
     */
    friend bool operator<=(BigNumber b1, const BigNumber &b2);

    //@{
    /**
     * Assignment operator
     * @param other - The new value for the BigNumber
     * @return A BigNumber containing the new value
     */
    BigNumber& operator=(const BigNumber &other);
    BigNumber& operator=(const long long &other);
    BigNumber& operator=(const std::string &other);
    //@}

    //@{
    /**
     * Addition assignment operator\n
     * Adds and assigns a value to the current instance
     * @param other - The value being added
     * @return The new value after addition and assignment
     */
    BigNumber& operator+=(const BigNumber &other);
    BigNumber& operator+=(const long long &other);
    BigNumber& operator+=(const std::string &other);
    //@}

    //@{
    /**
     * Subtraction assignment operator\n
     * Subtracts and assigns a value to the current instance
     * @param other - The value being subtracted
     * @return The new value after subtraction and assignment
     */
    BigNumber& operator-=(const BigNumber &other);
    BigNumber& operator-=(const long long &other);
    BigNumber& operator-=(const std::string &other);
    //@}

    //@{
    /**
     * Multiplication assignment operator\n
     * Multiplies and assigns a value to the current instance
     * @param other - The value being multiplied
     * @return The new value after multiplication and assignment
     */
    BigNumber& operator*=(const BigNumber &other);
    BigNumber& operator*=(const long long &other);
    BigNumber& operator*=(const std::string &other);
    //@}

    //@{
    /**
     * Division assignment operator\n
     * Divides and assigns a value to the current instance
     * @param other - The value being divided
     * @return The new value after division and assignment
     */
    BigNumber& operator/=(const BigNumber &other);
    BigNumber& operator/=(const long long &other);
    BigNumber& operator/=(const std::string &other);
    //@}

    /**
     * Pre-increment operator
     * @return The incremented BigNumber
     */
    BigNumber& operator++();

    /**
     * Pre-decrement operator
     * @return The decremented BigNumber
     */
    BigNumber& operator--();

    /**
     * Post-increment operator
     * @return The incremented BigNumber
     */
    BigNumber operator++(int);

    /**
     * Post-decrement operator
     * @return The decremented BigNumber
     */
    BigNumber operator--(int);

    /**
     * The index operator
     * @param index The position being looked at
     * @return The number at the specified position in the BigNumber string
     */
    unsigned int operator[](int index);

private:


    //Methods
    BigNumber addll(const long long &other);
    BigNumber addstr(const std::string &other);
    BigNumber subtractll(const long long &other);
    BigNumber subtractstr(const std::string  &other);
    BigNumber multiplyll(const long long &other);
    BigNumber multiplystr(const std::string &other);
    BigNumber dividell(const long long &other);
    BigNumber dividestr(const std::string &other);
};


BigNumber::BigNumber(std::string number) :
        _numberString(number)
{
}

BigNumber::BigNumber(long long number) :
    _numberString(std::to_string(number))
{}

BigNumber BigNumber::add(BigNumber other) {
    BigNumber b1 = other > *this ? other : *this;
    BigNumber b2 = other > *this ? *this : other;
    if (b1.isNegative() || b2.isNegative()) {
        if (b1.isNegative() && b2.isNegative()) {
            return b1.negate().add(b2.negate()).negate();
        }
        else if (b1.isNegative() && !b2.isNegative()) {
            return b1.negate().subtract(b2).negate();
        }
        else {
            return b2.negate().subtract(b1).negate();
        }
    }
    std::string results;
    int carry = 0;
    int diff = int(b1._numberString.size() - b2._numberString.size());
    for (int i = 0; i < diff; ++i) {
        b2._numberString.insert(b2._numberString.begin(), '0');
    }
    for (int i = int(b1._numberString.size() - 1); i >= 0; --i) {
        int sum = (b1._numberString[i] - '0') + (b2._numberString[i] - '0') + carry;
        carry = 0;
        if (sum <= 9 || i == 0) {
            results.insert(0, std::to_string(sum));
        }
        else {
            results.insert(0, std::to_string(sum % 10));
            carry = 1;
        }
    }
    return BigNumber(results);
}

BigNumber BigNumber::addll(const long long &other) {
    return this->add(BigNumber(other));
}

BigNumber BigNumber::addstr(const std::string &other) {
    return this->add(BigNumber(other));
}


BigNumber BigNumber::subtract(BigNumber other) {
    BigNumber b1 = *this, b2 = other;
    if (b1.isNegative() || b2.isNegative()) {
        if (b1.isNegative() && b2.isNegative()) {
            return b1.negate().subtract(b2.negate()).negate();
        }
        else if (b1.isNegative() && !b2.isNegative()) {
            return b1.negate().add(b2).negate();
        }
        else {
            return b2.negate().add(b1);
        }
    }
    std::string results;
    int n = 0, p = 0;
    bool takeOffOne = false;
    bool shouldBeTen = false;

    if (b1 < b2) {
        //Negative answer
        std::string t = b2.subtract(*this).negate().getString();
        for (unsigned int i = 1; i < t.length(); ++i) {
            if (t[i] != '0') break;
            t.erase(1, 1);
        }
        return BigNumber(t);
    }

    //This next if-block fixes the case where the digit difference is greater than 1
    //100 - 5 is an example. This code adds 0's to make it, for example, 100 - 05, which
    //allows the rest of the subtraction code to work.
    if (b1._numberString.size() - b2.getString().size() > 1) {
        for (unsigned long i = 0; i < b1._numberString.size() - b2.getString().size() - 1; ++i) {
            b2._numberString.insert(b2._numberString.begin(), '0');
        }
    }
    int i = int(b1._numberString.size() - 1);
    for (int j = int(b2._numberString.size() - 1); j >= 0; --j) {
        if (((b1._numberString[i] - '0') < (b2._numberString[j] - '0')) && i > 0) {
            n = char((b1._numberString[i] - '0') + 10);
            takeOffOne = true;
            if (j > 0 || b1._numberString[i - 1] != '0') {
                p = char((b1._numberString[i - 1] - '0') - 1);
                if (p == -1) {
                    p = 9;
                    shouldBeTen = true;
                }
                takeOffOne = false;
            }
            if (shouldBeTen) {
                int index = i - 1;
                for (int a = i - 1; (b1._numberString[a] - '0') == 0; --a) {
                    b1._numberString[a] = static_cast<char>(p + '0');
                    --index;
                }
                int t = (b1._numberString[index] - '0') - 1;
                b1._numberString[index] = static_cast<char>(t + '0');
            }
            b1._numberString[i - 1] = static_cast<char>(p + '0');
            shouldBeTen = false;
        }
        std::stringstream ss;
        if (((b1._numberString[i] - '0') == (b2._numberString[j] - '0'))) {
            ss << "0";
        }
        else {
            if (n <= 0) {
                ss << ((b1._numberString[i] - '0') - (b2._numberString[j] - '0'));
            }
            else {
                ss << (n - (b2._numberString[j] - '0'));
            }
        }

        results.insert(0, ss.str());
        --i;
        n = 0;
    }
    if (takeOffOne) {
        std::string number = "";
        for (int j = b1._numberString.length() - b2._numberString.length() - 1; j >= 0; --j) {
            if (b1._numberString[j] == '0') {
                number += "0";
                continue;
            }
            else {
                number.insert(number.begin(), b1._numberString[j]);
                int t = atoi(number.c_str());
                --t;
                b1._numberString.replace(0, number.size(), std::to_string(t));
                break;
            }
        }
    }
    while (i >= 0) {
        std::stringstream ss;
        if (i == 0) {
            if (b1._numberString[i] - '0' != 0) {
                ss << (b1._numberString[i] - '0');
                results.insert(0, ss.str());
            }
        }
        else {
            ss << (b1._numberString[i] - '0');
            results.insert(0, ss.str());
        }

        --i;
    }
    //In the case of all 0's, we only want to return one of them
    if (results.find_first_not_of('0') == std::string::npos) {
        results = "0";
    }
    else if (results[0] == '0') {
        int index = results.find_first_not_of('0');
        results = results.substr(index, results.length() - 1);
    }
    return BigNumber(results);
}

BigNumber BigNumber::subtractll(const long long &other) {
    return this->subtract(BigNumber(other));
}

BigNumber BigNumber::subtractstr(const std::string &other) {
    return this->subtract(BigNumber(other));
}

BigNumber BigNumber::multiply(BigNumber other) {
    BigNumber b1 = other > *this ? other : *this;
    BigNumber b2 = other > *this ? *this : other;
    if (b1.isNegative() || b2.isNegative()) {
        if (b1.isNegative() && b2.isNegative()) {
            return b1.negate().multiply(b2.negate());
        }
        else if (b1.isNegative() && !b2.isNegative()) {
            return b1.negate().multiply(b2).negate();
        }
        else {
            return b2.negate().multiply(b1).negate();
        }
    }
    if (b1 == 0 || b2 == 0) return 0;
    int carry = 0;
    int zeroCounter = 0;
    BigNumber b = 0;

    for (unsigned int i = 0; i < b1._numberString.size() - b2._numberString.size(); ++i) {
        b2._numberString.insert(b2._numberString.begin(), '0');
    }
    for (long long int i = (b2._numberString.size() - 1); i >= 0; --i) {
        std::string rr;
        for (long long int j = int(b1._numberString.size() - 1); j >= 0; --j) {
            int val = ((b2._numberString[i] - '0') * (b1._numberString[j] - '0')) + carry;
            carry = 0;
            if (val > 9 && j != 0) {
                carry = val / 10;
                rr.insert(0, std::to_string(val % 10));
            }
            else {
                rr.insert(0, std::to_string(val));
            }
        }
        if (zeroCounter > 0) {
            for (int x = 0; x < zeroCounter; ++x) {
                rr.append("0");
            }
        }
        ++zeroCounter;
        b += BigNumber(rr);
    }
    if (b._numberString.find_first_not_of('0') != std::string::npos) {
        b.setString(b._numberString.erase(0, b._numberString.find_first_not_of('0')));
    }
    else {
        //In the case of all 0's, we only want to return one of them
        b.setString("0");
    }
    return b;
}

BigNumber BigNumber::multiplyll(const long long &other) {
    if (other == 0)
        return 0;
    if (other == 1)
        return *this;
    auto original = *this;
    for (auto i = 0; i < other - 1; ++i) {
        *this += original;
    }
    return *this;
}

BigNumber BigNumber::multiplystr(const std::string &other) {
    return this->multiply(BigNumber(other));
}

BigNumber BigNumber::divide(BigNumber other) {
    if (other == 0) {
        std::cerr << "You cannot divide by 0!" << std::endl;
    }
    BigNumber b1 = *this, b2 = other;
    bool sign = false;
    if (b1.isNegative() && b2.isNegative()) {
        b1.negate();
        b2.negate();
    }
    else if (b1.isNegative() && !b2.isNegative()) {
        b1.negate();
        sign = true;
    }
    else if (!b1.isNegative() && b2.isNegative()) {
        b2.negate();
        sign = true;
    }
    BigNumber quotient = 0;
    while (b1 >= b2) {
        b1 -= b2;
        ++quotient;
    }
    if (sign) quotient.negate();
    return quotient;
}

BigNumber BigNumber::dividell(const long long &other) {
    return this->divide(BigNumber(other));
}

BigNumber BigNumber::dividestr(const std::string &other) {
    return this->divide(BigNumber(other));
}

BigNumber BigNumber::pow(int exponent) {
    if (exponent < 0) std::cerr << "Powers less than 0 are not supported" << std::endl;
    if (exponent == 0) return BigNumber("1");
    if (exponent == 1) return *this;
    BigNumber result = 1, base = *this;
    while (exponent) {
        if (exponent & 1) {
            result *= base;
        }
        exponent >>= 1;
        base *= base;
    }
    return result;
}

std::string BigNumber::getString() {
    return this->_numberString;
}

BigNumber BigNumber::setString(const std::string &newStr) {
    this->_numberString = newStr;
    return *this;
}

BigNumber BigNumber::negate() {
    if (this->_numberString[0] == '-') {
        this->_numberString.erase(0, 1);
    }
    else {
        this->_numberString.insert(this->_numberString.begin(), '-');
    }
    return *this;
}

BigNumber BigNumber::trimLeadingZeros() {
    BigNumber b = *this;
    if (b._numberString.find_first_not_of('0') != std::string::npos) {
        b.setString(b._numberString.erase(0, b._numberString.find_first_not_of('0')));
    }
    return b;
}

bool BigNumber::equals(const BigNumber &other) {
    return this->_numberString == other._numberString;
}

bool BigNumber::equals(const long long &other) {
    return this->getString() == std::to_string(other);
}

bool BigNumber::equals(const std::string &other) {
    return this->getString() == other;
}

unsigned int BigNumber::digits() {
    return this->_numberString.length() - static_cast<int>(this->isNegative());
}

bool BigNumber::isNegative() const {
    return this->_numberString[0] == '-';
}

bool BigNumber::isPositive() {
    return !this->isNegative();
}

bool BigNumber::isEven() {
    return this->_numberString[this->_numberString.length() - 1] % 2 == 0;
}

bool BigNumber::isOdd() {
    return !this->isEven();
}

BigNumber BigNumber::abs() const {
    return BigNumber(this->_numberString.substr(static_cast<unsigned int>(this->isNegative())));
}

std::ostream &operator<<(std::ostream &os, const BigNumber &num) {
    os << num._numberString;
    return os;
}

BigNumber operator+(BigNumber b1, const BigNumber &b2) {
    return b1.add(b2);
}

BigNumber operator+(BigNumber b1, const long long &b2) {
    return b1.addll(b2);
}

BigNumber operator+(BigNumber b1, const std::string &b2) {
    return b1.addstr(b2);
}

BigNumber operator-(BigNumber b1, const BigNumber &b2) {
    return b1.subtract(b2);
}

BigNumber operator-(BigNumber b1, const long long &b2) {
    return b1.subtractll(b2);
}

BigNumber operator-(BigNumber b1, const std::string &b2) {
    return b1.subtractstr(b2);
}

BigNumber operator*(BigNumber b1, const BigNumber &b2) {
    return b1.multiply(b2);
}

BigNumber operator*(BigNumber b1, const long long &b2) {
    return b1.multiplyll(b2);
}

BigNumber operator*(BigNumber b1, const std::string &b2) {
    return b1.multiplystr(b2);
}

BigNumber operator/(BigNumber b1, const BigNumber &b2) {
    return b1.divide(b2);
}

BigNumber operator/(BigNumber b1, const long long &b2) {
    return b1.dividell(b2);
}

BigNumber operator/(BigNumber b1, const std::string &b2) {
    return b1.dividestr(b2);
}

BigNumber operator^(BigNumber b1, const int &b2) {
    return b1.pow(b2);
}

bool operator==(BigNumber b1, const BigNumber &b2) {
    return b1.equals(b2);
}

bool operator==(BigNumber b1, const long long &b2) {
    return b1.equals(b2);
}

bool operator==(BigNumber b1, const std::string &b2) {
    return b1.equals(b2);
}

bool operator>(BigNumber b1, const BigNumber &b2) {
    if (b1.isNegative() || b2.isNegative()) {
        if (b1.isNegative() && b2.isNegative()) {
            BigNumber bt = b2;
            b1._numberString.erase(0, 1);
            bt._numberString.erase(0, 1);
            return b1 < bt;
        }
        else {
            return !(b1.isNegative() && !b2.isNegative());
        }
    }
    b1 = b1.trimLeadingZeros();
    auto c = BigNumber(b2);
    c = c.trimLeadingZeros();
    if (b1 == c) {
        return false;
    }
    if (b1._numberString.size() > c._numberString.size()) {
        return true;
    }
    else if (c._numberString.size() > b1._numberString.size()) {
        return false;
    }
    else {
        for (unsigned int i = 0; i < b1._numberString.size(); ++i) {
            if (b1[i] == static_cast<unsigned int>(c._numberString[i] - '0')) {
                continue;
            }
            return b1[i] > static_cast<unsigned int>(c._numberString[i] - '0');
        }
    }
    return false;
}

bool operator<(BigNumber b1, const BigNumber &b2) {
    return !(b1 == b2) && !(b1 > b2);
}

bool operator>=(BigNumber b1, const BigNumber &b2) {
    return b1 > b2 || b1 == b2;
}

bool operator<=(BigNumber b1, const BigNumber &b2) {
    return b1 < b2 || b1 == b2;
}

unsigned int BigNumber::operator[](int index) {
    if (this->_numberString[index] == '-') {
        std::cerr << "You cannot get the negative sign from the number" << std::endl;
    }
    return static_cast<unsigned int>(this->_numberString[index] - '0');
}

BigNumber& BigNumber::operator=(const BigNumber &other) {
    this->_numberString = other._numberString;
    return *this;
}

BigNumber& BigNumber::operator=(const long long &other) {
    this->_numberString = std::to_string(other);
    return *this;
}

BigNumber& BigNumber::operator=(const std::string &other) {
    this->_numberString = other;
    return *this;
}

BigNumber& BigNumber::operator+=(const BigNumber &other) {
    *this = *this + other;
    return *this;
}

BigNumber& BigNumber::operator+=(const long long &other) {
    *this = *this + other;
    return *this;
}

BigNumber& BigNumber::operator+=(const std::string &other) {
    *this = *this + other;
    return *this;
}

BigNumber& BigNumber::operator-=(const BigNumber &other) {
    *this = *this - other;
    return *this;
}

BigNumber& BigNumber::operator-=(const long long &other) {
    *this = *this - other;
    return *this;
}

BigNumber& BigNumber::operator-=(const std::string &other) {
    *this = *this - other;
    return *this;
}

BigNumber& BigNumber::operator*=(const BigNumber &other) {
    *this = *this * other;
    return *this;
}

BigNumber& BigNumber::operator*=(const long long &other) {
    *this = *this * other;
    return *this;
}

BigNumber& BigNumber::operator*=(const std::string &other) {
    *this = *this * other;
    return *this;
}

BigNumber& BigNumber::operator/=(const BigNumber &other) {
    *this = *this / other;
    return *this;
}

BigNumber& BigNumber::operator/=(const long long &other) {
    *this = *this / other;
    return *this;
}

BigNumber& BigNumber::operator/=(const std::string &other) {
    *this = *this / other;
    return *this;
}

BigNumber& BigNumber::operator++() {
    *this += BigNumber("1");
    return *this;
}

BigNumber& BigNumber::operator--() {
    *this -= BigNumber("1");
    return *this;
}

BigNumber BigNumber::operator++(int) {
    BigNumber t(this->getString());
    ++(*this);
    return t;
}

BigNumber BigNumber::operator--(int) {
    BigNumber t(this->getString());
    --(*this);
    return t;
}

void schonhageStrassenMultiplication(string s1, string s2) {
    long long n = s1.size();
    long long m = s2.size();
    BigNumber a = BigNumber(s1);
    BigNumber b = BigNumber(s2);

   int linearConvolution[n + m-1];
   for (int i = 0; i < (n + m-1); i++)
      linearConvolution[i] = 0;
      BigNumber p = a;
   for (int i = 0; i < m; i++) {
      a = p;
      for (int j = 0; j < n; j++) {
        if (b._numberString.size() && a._numberString.size()){
            linearConvolution[i + j] += (b._numberString[b._numberString.size()-1]-'0') * (a._numberString[a._numberString.size()-1]-'0');
            a._numberString.pop_back();
        }
      }
      if (b._numberString.size())
        b._numberString.pop_back();
   }

   BigNumber product = 0;
   long nextCarry = 0;
   BigNumber base = 1;
   for (int i = 0; i < n + m; i++) {
      linearConvolution[i] += nextCarry;
      product = product + (base * (linearConvolution[i] % 10));
      nextCarry = linearConvolution[i] / 10;
      base *= 10;
   }
   cout << product._numberString;
}
int main() {
   string a, b;
   cin >> a >> b;

   schonhageStrassenMultiplication(a, b);
}

Test details

Test 1

Verdict: ACCEPTED

input
8
5

correct output
40

user output
40

Test 2

Verdict: ACCEPTED

input
9
1

correct output
9

user output
9

Test 3

Verdict: ACCEPTED

input
9
5

correct output
45

user output
45

Test 4

Verdict: ACCEPTED

input
2
5

correct output
10

user output
10

Test 5

Verdict: ACCEPTED

input
8
7

correct output
56

user output
56

Test 6

Verdict:

input
48
92

correct output
4416

user output
9416

Test 7

Verdict:

input
1
40

correct output
40

user output
740

Test 8

Verdict:

input
97
74

correct output
7178

user output
2178

Test 9

Verdict:

input
58
8

correct output
464

user output
964

Test 10

Verdict:

input
15
24

correct output
360

user output
5360

Test 11

Verdict: ACCEPTED

input
4
7

correct output
28

user output
28

Test 12

Verdict: ACCEPTED

input
906
417

correct output
377802

user output
377802

Test 13

Verdict: ACCEPTED

input
778
105

correct output
81690

user output
81690

Test 14

Verdict:

input
2
989

correct output
1978

user output
6978

Test 15

Verdict:

input
2830
5329

correct output
15081070

user output
65081070

Test 16

Verdict: ACCEPTED

input
9
51382

correct output
462438

user output
462438

Test 17

Verdict: ACCEPTED

input
25053
71372

correct output
1788082716

user output
1788082716

Test 18

Verdict:

input
258180
674616

correct output
174172358880

user output
674172358880

Test 19

Verdict:

input
8821
2

correct output
17642

user output
(empty)

Error:
munmap_chunk(): invalid pointer

Test 20

Verdict: ACCEPTED

input
1742712
9600618

correct output
16731112196016

user output
16731112196016

Test 21

Verdict: ACCEPTED

input
8898606
2936506

correct output
26130809910636

user output
26130809910636

Test 22

Verdict:

input
82670092
60138633

correct output
4971666322864236

user output
9971666322864236

Test 23

Verdict:

input
54746871
83822602

correct output
4589025178578342

user output
9589025178578342

Test 24

Verdict:

input
477252461
1032684

correct output
492850980435324

user output
5492850980435324

Test 25

Verdict: ACCEPTED

input
5932935
379

correct output
2248582365

user output
2248582365

Test 26

Verdict:

input
620114
3126641

correct output
1938873857074

user output
(empty)

Error:
munmap_chunk(): invalid pointer

Test 27

Verdict: ACCEPTED

input
452757081
222748761

correct output
100851078826726641

user output
100851078826726641

Test 28

Verdict: ACCEPTED

input
689748332
888826746

correct output
613066765490487672

user output
613066765490487672

Test 29

Verdict:

input
111337
25

correct output
2783425

user output
52783425

Test 30

Verdict:

input
809
84435378

correct output
68308220802

user output
38308220802

Test 31

Verdict:

input
9641697369926504411
425970950212942028697061039529...

correct output
410708299033321711216812810174...

user output
910708299033321711216812810174...

Test 32

Verdict:

input
793769623129909085108356241071...

correct output
264404012608186879272715560773...

user output
964404012608186879272715560773...

Test 33

Verdict:

input
8539777831492675800
436

correct output
3723343134530806648800

user output
723343134530806648800

Test 34

Verdict:

input
946492187160898604892390431179...

correct output
585982368537725512535970251461...

user output
285982368537725512535970251461...

Test 35

Verdict:

input
874046401974324184707688863838...

correct output
174556202198322810668657866310...

user output
874556202198322810668657866310...

Test 36

Verdict:

input
168584663428092347854539803060...

correct output
235958453587245776929148968707...

user output
723595845358724577692914896870...

Test 37

Verdict:

input
279013912031336395843652482056...

correct output
856375236460411618343887929304...

user output
785637523646041161834388792930...

Test 38

Verdict:

input
909594443312661242668561455177...

correct output
801297086685128929836268694647...

user output
501297086685128929836268694647...

Test 39

Verdict:

input
521558480102200460144622364590...

correct output
403176935665359352292583479223...

user output
103176935665359352292583479223...

Test 40

Verdict: ACCEPTED

input
198766521920629467015839613580...

correct output
197951285207558548760833360414...

user output
197951285207558548760833360414...

Test 41

Verdict:

input
388239940637354291806784217812...

correct output
354893636094929851749498258576...

user output
548936360949298517494982585766...

Test 42

Verdict:

input
580031950564534684773525167998...

correct output
225288306472433597677862095876...

user output
525288306472433597677862095876...

Test 43

Verdict:

input
673497493525004204568833306269...

correct output
104167516519697053781119530996...

user output
804167516519697053781119530996...

Test 44

Verdict:

input
583582406474458495157747860432...

correct output
355985267949419682046226194863...

user output
559852679494196820462261948638...

Test 45

Verdict:

input
154401310284121033413839709675...

correct output
472687322036571910421947159369...

user output
747268732203657191042194715936...

Test 46

Verdict:

input
964784520177212016698
135881607827957154173561484162...

correct output
131096471809203739325264543904...

user output
631096471809203739325264543904...

Test 47

Verdict:

input
506417941420848908877158785176...

correct output
124940484872553056181800567857...

user output
824940484872553056181800567857...

Test 48

Verdict:

input
278205703909200971326699489015...

correct output
213362541886605761113025837459...

user output
913362541886605761113025837459...

Test 49

Verdict:

input
488919747667763730629078434642...

correct output
244261035002054726047225565934...

user output
144261035002054726047225565934...

Test 50

Verdict:

input
683013292533355268532590162229...

correct output
271255985219635665074840248062...

user output
971255985219635665074840248062...

Test 51

Verdict:

input
701382950383712289025758984281...

correct output
396240397875971182850884660551...

user output
896240397875971182850884660551...

Test 52

Verdict:

input
950530137216618089651057517232...

correct output
525100658977646195130452101103...

user output
225100658977646195130452101103...

Test 53

Verdict:

input
758180874616256083097058082046...

correct output
612777382638418549100062437996...

user output
312777382638418549100062437996...

Test 54

Verdict:

input
282198270649528096385750216226...

correct output
878945962031578099916769892430...

user output
187894596203157809991676989243...

Test 55

Verdict:

input
374271236006180996628555027124...

correct output
205927043926518428842129271440...

user output
905927043926518428842129271440...

Test 56

Verdict:

input
789860669365068182777748873091...

correct output
369460448033120451265094062370...

user output
(empty)

Test 57

Verdict:

input
826700926013863385104801713448...

correct output
291751287859134397942962144651...

user output
(empty)

Test 58

Verdict:

input
947468718382260248801518078140...

correct output
226868697296935607336651841496...

user output
(empty)

Test 59

Verdict:

input
177252461103268440789803954968...

correct output
111876380249200192763403085310...

user output
(empty)

Test 60

Verdict:

input
393293577943612353036749957226...

correct output
336630505716557163667422969707...

user output
(empty)

Test 61

Verdict:

input
320114112664152374910455416563...

correct output
136407754249269979820422504376...

user output
(empty)

Test 62

Verdict:

input
152757081122748761316522074282...

correct output
107712372482584798763194835348...

user output
(empty)

Test 63

Verdict:

input
889748332988826746683887083103...

correct output
729454517423131565738173030712...

user output
(empty)

Test 64

Verdict:

input
311337350148998951898280698942...

correct output
245742878826375358332482490843...

user output
(empty)

Test 65

Verdict:

input
709744353788876782171034561202...

correct output
198288295923437797210097622398...

user output
(empty)