CSES Divisor Analysis solution

I have written this code for the problem :
#include <bits/stdc++.h>
using namespace std;

#define fastio cin.tie(0)->sync_with_stdio(0), cin.exceptions(cin.failbit);
#define nl ‘\n’
#define spb ’ ’
#define ff first
#define ss second
#define pb push_back
#define popb pop_back
#define loop(i,m,n) for(ll i = m; i < n; i++)
#define rloop(i,m,n) for(ll i = m; i >= n;i–)
#define ll long long
#define lld long double
#define all(x) (x).begin(), (x).end()
#define input(x) for(auto &val:x) cin>>val

// ************* Debugging infra *************//
#ifdef LOCAL
#include “D:/Code/IncludeResources/getDebug.hpp”
#define debug(x) cerr << #x <<" "; _print(x); cerr << endl;
#else
#define debug(x)
#endif

//********************** Constants *********************//
const lld pi = 3.141592653589793238;
const ll INF = 1e18;
const ll mod = 1e9 + 7;

//********************** Typedef ********************//
using pll = pair<ll, ll>;
using vll = vector ;
using vch = vector ;
using vpll = vector ;

using qull = queue ;
using dqll = deque ;
using pqll = priority_queue ;
using pqminll = priority_queue<ll, vector, greater> ;

using setll = set ;
using mapll = map<ll, ll> ;
using unsetll = unordered_set ;
using unmapll = unordered_map<ll, ll> ;
using mlsetll = multiset ;
using mmpll = multimap<ll, ll> ;

vpll fact;
vector primes;

bool isPrime(ll n)
{
if (n == 1) return false;
for (ll i{2}; i * i <= n; ++i)
{
if (n % i == 0)
return false;
}
return true;
}

ll modExp(ll a, ll n, ll md)
{
a %= md;
ll res = 1;
while (n)
{
if (n & 1)
res = res * a % md;
a = a * a % md;
n >>= 1;
}
return res;
}

void getSieve(ll n)
{
primes.resize(n + 1, 1);
primes[1] = false;
for (ll i{2}; i * i <= n; ++i)
{
if (primes[i])
{
for (ll j{i * i}; j <= n; j += i)
primes[j] = 0;
}
}
}

void preCalFac(ll n)
{
fact.resize(n + 1);
fact[0].ff = fact[1].ff = 1;
loop(i, 2, n + 1)
fact[i].ff = (fact[i - 1].ff * i) % mod;

fact[n].ss = modExp(fact[n].ff, mod - 2, mod);

rloop(i, n - 1, 0)
fact[i].ss = (fact[i + 1].ss * (i + 1)) % mod;

}

void solve()
{
ll n; cin >> n;
vpll vec(n);

ll cnt = 1, cnt2 = 1, sum = 1;
for (auto &p : vec)
{
    cin >> p.ff >> p.ss;
    cnt *= (p.ss + 1);
    cnt2 *= (p.ss + 1);
    cnt %= mod;
    cnt2 %= 2 * (mod - 1);

// the above line had bug when I was doing % (mod-1) only , but I don’t understand how this gets fixed by doing this , suggested by chatgpt

    sum *= (((modExp(p.ff, p.ss + 1, mod) - 1 + mod) % mod) * modExp(p.ff - 1, mod - 2, mod)) % mod;
    sum %= mod;
}

ll prod = 1;
bool isSq = true;
for (auto &p : vec)
{
    if (p.ss & 1)
    {
        isSq = false;
        break;
    }
}

if (isSq)
{
    for (auto &p : vec)
    {
        prod *= modExp(p.ff, p.ss / 2, mod);
        prod %= mod;
    }

    prod = modExp(prod, cnt2, mod);
}
else
{
    ll base = 1;
    for (auto &p : vec)
    {
        base *= modExp(p.ff, p.ss, mod);
        base %= mod;
    }

    // cnt >>= 1;
    prod = modExp(base, cnt2 / 2 , mod);
}

cout << cnt  << spb << sum << spb << prod << nl;

}

int main()
{
fastio
int t = 1;
// cin >> t;
while (t–) solve();
return 0;
}

Can anyone help me out ?