Multiplying and Adding Large Numbers
It's really worth making your big number be a class.  This will give you the ability to

change the internal representation without altering client code
write operators (+, -, /, *, &lt;, ==, &lt;&lt; and more) that work just like they do for other numbers
specialize numeric limits and other traits classes so they can be used as arithmetic types in algorithms. For example, you might like a std::complex&lt;BigNum&gt;.  You can have one, but a std::complex&lt;std::vector&lt;int&gt;&gt; isn't going to work.
add literal operators so that you can write them naturally in your source code.

You don't have to do all the above at once, of course.  But I recommend you read the review of Implementation of a Rational Number class in C++ to see how an arithmetic class can work.
Your main() would then be isolated from the implementation details, and look something like
#include &lt;bignum&gt;

int main () {
    int N = 100;
    auto fac = 1_big;
    do {
        fac *= N;
    } while (--N &gt; 0);

    std::cout &lt;&lt; &quot;100! = &quot; &lt;&lt; fac &lt;&lt; std::endl;
}


Space efficiency
Once you have your class, you'll observe that writing one digit in each int is quite wasteful.  char is defined to include at least 0 to 127 so you could store two digits (0 to 100) in each element of a vector of characters.
If you've made your big number a class, it's then easier to do this in two steps - first store one digit in each character, and then widen to 2 per char.  There are more space-efficient encodings; you'll have to decide where the trade-off between space and time lies for your needs.

Temporary values in multiplication
In your long multiplication, you store all the intermediate results before adding them together.  You can save some of this space by using an accumulator variable to add the results as you go, like this pseudo-code:
accumulator = 0
for i in digits
     tmp = arg1 * i
     accumulator += tmp
return accumulator

Then you no longer need to have a vector of partial products throughout the function.

Working example
Here's what I implemented, following the notes above.  It's the absolute minimum needed to calculate factorials.  Several features are left as an exercise:

Implement a user-defined literal that accepts longer numbers than unsigned long long can represent
Support negative numbers
Implement the other arithmetic and relational operators
Make more of the implementation constexpr so it can be evaluated during compilation


#include &lt;vector&gt;
#include &lt;iosfwd&gt;

class Bignum
{
    static constexpr char max_digit = 100;

    std::vector&lt;char&gt; digits = {};   // smallest centits first

public:
    Bignum(unsigned long long int n)
    {
        while (n) {
            digits.push_back(n % max_digit);
            n /= max_digit;
        }
    }
    // copy constructor and assignment operator can be defaulted

    Bignum&amp; operator+=(const Bignum&amp; other);
    Bignum operator+(const Bignum&amp; other) const;

    Bignum&amp; operator*=(const Bignum&amp; other);

    friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const Bignum&amp;);

private:
    // helper functions
    Bignum&amp; halve();
    Bignum&amp; trim();
};

Bignum operator&quot;&quot;_big(unsigned long long n) { return n; }


// IMPLEMENTATION

#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;utility&gt;

Bignum&amp; Bignum::operator+=(const Bignum&amp; other)
{
    int sum = 0;
    auto i = digits.begin();
    auto j = other.digits.begin();
    bool in = true;             // until i reaches digits.end()
    bool jn = true;
    while ((in &amp;= i != digits.end()) | (jn &amp;= j != other.digits.end()) || sum) {
        if (jn)
            sum += *j++;
        if (in) {
            sum += *i;
            *i++ = sum % max_digit;
        } else {
            digits.push_back(sum % max_digit);
        }
        sum /= max_digit;       // carry to next digit
    }
    return *this;
}

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


Bignum&amp; Bignum::operator*=(const Bignum&amp; other)
{
    Bignum a = *this, b = other;
    if (a.digits.size() &gt; b.digits.size())
        std::swap(a, b);

    digits.clear();
    while (a.digits.size() &gt; 0) {
        if (a.digits.front() % 2)
            *this += b;
        a.halve();
        b += b;
    }
    return *this;
}

Bignum&amp; Bignum::halve()
{
    int carry = 0;
    for (auto i = digits.rbegin();  i != digits.rend();  ++i) {
        carry *= max_digit;
        carry += *i;
        *i = carry / 2;
        carry = carry % 2;
    }
    return trim();
}

Bignum&amp; Bignum::trim()
{
    while (digits.size() &gt; 0 &amp;&amp; !digits.back())
        digits.pop_back();
    return *this;
}

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const Bignum&amp; n)
{
    if (n.digits.size() == 0)
        return out &lt;&lt; '0';

    bool z = false;             // track leading zeros
    for (auto i = n.digits.rbegin();  i != n.digits.rend();  ++i) {
        int n = *i;
        if (z |= n/10)
            out &lt;&lt; n/10;
        if (z |= n)
            out &lt;&lt; n % 10;
    }

    return out;
}


// PROGRAM

int main () {
    const int N = 100;
    auto fac = 1_big;

    for (int i = 1;  i &lt; N;  ++i) {
        fac *= i;
        std::cout &lt;&lt; i &lt;&lt; &quot;! = &quot; &lt;&lt; fac &lt;&lt; std::endl;
    };
}