Submission #49973893


Source Code Expand

/**
 *  @the_hyp0cr1t3
 *  03.02.2024 18:49
**/
#include <bits/stdc++.h>

#if __cplusplus < 202002L
namespace std {
    template <typename T>
    constexpr int ssize(const T &s) { return s.size(); }
}
#endif

// commonly used:
//  decimal <10, 9, '0'>
//  alphabet <26, 6, 'a'>
//  binary  <2, 30, '0'>
template <int base = 10, int grpsz = 9, char base_char = '0'>
struct bigint {
    static constexpr auto t = []() {
        std::array<int, grpsz + 1> p{1};
        int n = 0, m = 0;
        for (int i = 1; i <= grpsz; ++i) {
            p[i] = p[i - 1] * base;
            if (p[i] <= 1000000) n = i;
        }
        m = p.back();
        return std::make_tuple(m, n, p);
    }();

    // base should not exceed 1e9 (overflow)
    static constexpr int _mod = std::get<0>(t);
    static constexpr int reduced_grpsz = std::get<1>(t);
    static constexpr std::array<int, grpsz + 1> pows = std::get<2>(t);
    static constexpr int karatsubaMinimalSize = 50;

    int sign{1};
    std::vector<int> d;

    // ctors
    bigint(int64_t number = 0) {
        sign = number < 0 ? number = -number, -1 : 1;
        while (number > 0)
            d.emplace_back(number % _mod), number /= _mod;
    }
    // _digits = MSB...LSB (not in groups of size grpsz); sign = -1 || 1
    bigint(const std::vector<int>& _digits, int _sign = 1): sign(_sign) {
        d.reserve(std::ssize(_digits) / grpsz + 1);
        for (int i = std::ssize(_digits) - 1, block = 0; i >= 0; i -= grpsz, block = 0) {
            for (int j = std::max(0, i - grpsz + 1); j <= i; j++)
                block = block * base + _digits[j];
            d.emplace_back(block);
        }
        normalize();
    }
    bigint(const std::string& s): bigint(convert_string_to_vector(s), (s[0] == '-' ? -1 : 1)) {}

    // does not handle overflow
    template<typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
    explicit operator T() const {
        T res = 0;
        for (auto& _d: d)
            res = res * _mod + _d;
        return res * sign;
    }

// io
    std::string to_string() const {
        std::string s;
        if (is0()) s += base_char;
        else {
            for (auto res: d)
                for (int j = 0; j < grpsz; j++)
                    s += res % base + base_char, res /= base;
            while (s.size() and s.back() == base_char) s.pop_back();
            if (sign < 0) s += '-';
            std::reverse(s.begin(), s.end());
        }
        return s;
    }

    friend std::istream& operator>>(std::istream& is, bigint& number) {
        std::string s;
        is >> s;
        number = bigint(s);
        return is;
    }
    friend std::ostream& operator<<(std::ostream& os, const bigint& number) {
        return os << number.to_string();
    }

// helpers
    inline bool is0() const noexcept { return !d.size(); }
    inline void normalize() noexcept {
        while (d.size() and !d.back()) d.pop_back();
        if (!d.size()) sign = 1;
    }
    static std::vector<int> convert_string_to_vector(const std::string& s) {
        std::vector<int> v;
        v.reserve(s.size());
        for (auto c: s)
            if (c != '-') v.emplace_back(c - base_char);
        return v;
    }

// compare
    int compare(const bigint& o) const noexcept {
        if (sign != o.sign) return sign == 1 ? 1 : -1;
        if (std::ssize(d) > std::ssize(o.d)) return sign == 1 ? 1 : -1;
        if (std::ssize(d) < std::ssize(o.d)) return sign == 1 ? -1 : 1;
        for (int i = std::ssize(d) - 1; i >= 0; --i) {
            if (d[i] > o.d[i]) return sign == 1 ? 1 : -1;
            if (d[i] < o.d[i]) return sign == 1 ? -1 : 1;
        }
        return 0;
    }

    bool operator< (const bigint& o) const noexcept { return compare(o) < 0; }
    bool operator> (const bigint& o) const noexcept { return compare(o) > 0; }
    bool operator==(const bigint& o) const noexcept { return compare(o) == 0; }
    bool operator<=(const bigint& o) const noexcept { return compare(o) <= 0; }
    bool operator>=(const bigint& o) const noexcept { return compare(o) >= 0; }
    bool operator!=(const bigint& o) const noexcept { return compare(o) != 0; }

// operator overloads
    int operator[](size_t idx) const noexcept { return d[idx]; }
    bigint operator-() const { bigint res = *this; res.sign *= -1; return res; }
    bigint abs() const { bigint res = *this; res.sign *= res.sign; return res; }

    void increment() {
        for (auto& _d: d) { if (++_d < _mod) return; _d = 0; }
        d.emplace_back(1);
    }
    void decrement() {
        if (is0()) { sign = -1; d.emplace_back(1); }
        else { for (auto& _d: d) { if (_d--) return normalize(); _d = _mod - 1; } }
    }

    bigint& operator++() { sign > 0 ? increment() : decrement(); return *this; }
    bigint& operator--() { sign > 0 ? decrement() : increment(); return *this; }
    bigint operator++(int) { bigint res = *this; ++*this; return res; }
    bigint operator--(int) { bigint res = *this; --*this; return res; }

    bigint& operator+=(const int64_t num) {
        if ((sign > 0) != (num > 0)) return *this -= bigint(-num);
        if (num >= _mod) return *this += bigint(num);
        int carry = num;
        for (int pos = 0; pos < std::ssize(d) and carry; pos++) {
            d[pos] += carry;
            carry = d[pos] >= _mod;
            if (carry) d[pos] -= _mod;
        }
        if (carry) d.emplace_back(1);
        return normalize(), *this;
    }

    bigint& operator+=(const bigint& o) {
        if (sign != o.sign) return *this -= -o;
        d.resize(std::max(std::ssize(d), std::ssize(o.d)));
        int carry = 0;
        for (int pos = 0; pos < std::ssize(d); pos++) {
            d[pos] += carry + (pos < std::ssize(o.d) ? o.d[pos] : 0);
            carry = d[pos] >= _mod;
            if (carry) d[pos] -= _mod;
        }
        if (carry) d.emplace_back(1);
        return *this;
    }

    bigint& operator-=(const bigint& o) {
        if (sign != o.sign) return *this += -o;
        if (o.abs() > abs()) return *this = -(o - *this);
        int carry = 0;
        for (int pos = 0; pos < std::ssize(o.d) or carry; pos++) {
            d[pos] -= carry + (pos < std::ssize(o.d) ? o.d[pos] : 0);
            carry = d[pos] < 0;
            if (carry) d[pos] += _mod;
        }
        return normalize(), *this;
    }

    bigint operator+(const bigint& o) const { bigint res = *this; res += o; return res; }
    bigint operator-(const bigint& o) const { bigint res = *this; res -= o; return res; }

    bigint& operator*=(int num) {
        if (num < 0) sign = -sign, num = -num;
        if (num >= _mod) return *this *= bigint(num), *this;
        int64_t rem = 0;
        for (auto& i : d) {
            rem += 1LL * i * num;
            int64_t div = rem / _mod;
            i = rem - div*_mod;
            rem = div;
        }
        if (rem > 0) d.emplace_back(rem);
        return normalize(), *this;
    }

    bigint operator*(int num) const { bigint res = *this; res *= num; return res; }
    bigint operator*=(const bigint& o) { return *this = *this * o; }

    bigint operator*(const bigint &o) const {
        std::vector<int64_t> U = convert_base<int64_t>(d, grpsz, reduced_grpsz);
        std::vector<int64_t> V = convert_base<int64_t>(o.d, grpsz, reduced_grpsz);
        int32_t _sz = std::max(std::ssize(U), std::ssize(V));
        _sz--; _sz |= _sz >> 1; _sz |= _sz >> 2; _sz |= _sz >> 4;
        _sz |= _sz >> 8; _sz |= _sz >> 16; _sz++;
        U.resize(_sz); V.resize(_sz);
        std::vector<int64_t> ret = karatsubaMultiply(U, V, 0, _sz);
        bigint res; res.sign = sign * o.sign;
        res.d.reserve(std::ssize(ret));
        for (int i = 0, carry = 0; i < std::ssize(ret); i++) {
            int64_t cur = ret[i] + carry;
            res.d.emplace_back(cur % pows[reduced_grpsz]);
            carry = cur / pows[reduced_grpsz];
        }
        res.d = convert_base<int>(res.d, reduced_grpsz, grpsz);
        res.normalize();
        return res;
    }

    bigint& operator/=(int num) {
        assert(num && "Divide by zero");
        if (num >= _mod) return *this /= bigint(num);
        if (num < 0) sign = -sign, num = -num;
        int64_t rem = 0;
        for (int j = std::ssize(d) - 1; ~j; j--) {
            (rem *= _mod) += d[j];
            int64_t div = rem / num;
            d[j] = div;
            rem -= div * num;
        }
        return normalize(), *this;
    }

    int operator%(int num) const {
        assert(num && "Divide by zero");
        if (num < 0) num = -num;
        int64_t rem = 0;
        for (int i = std::ssize(d) - 1; i >= 0; i--)
            ((rem *= _mod) += d[i]) %= num;
        return rem * sign;
    }

    bigint operator/(int num) const { bigint res = *this; res /= num; return res; }
    bigint& operator/=(const bigint& o) { return *this = div_mod(o).first; }
    bigint operator/(const bigint& o) const { return div_mod(o).first; }
    bigint& operator%=(const bigint& o) { return *this = div_mod(o).second; }
    bigint operator%(const bigint& o) const { return div_mod(o).second; }
    bigint operator^(const bigint& o) const {   // exponentiate
        bigint res{1}, A = *this, B = o;
        while (!B.is0()) {
            if (B % 2) res *= A;
            B /= 2; A *= A;
        }
        return res;
    }

// Misc.
    template<typename T>
    static std::vector<T> convert_base(const std::vector<int>& v, int from_cnt, int to_cnt) {
        std::vector<T> res; int64_t cur = 0, have = 0;
        for (int i = 0; i < std::ssize(v); i++) {
            cur += 1LL * pows[have] * v[i];
            have += from_cnt;
            while (have >= to_cnt) {
                res.emplace_back(cur % pows[to_cnt]);
                cur /= pows[to_cnt]; have -= to_cnt;
            }
        }
        res.emplace_back(cur);
        while (!res.empty() && !res.back()) res.pop_back();
        return res;
    }

    static inline std::vector<int64_t> karatsubaSum(const std::vector<int64_t>& V, int pos, int len) {
        std::vector<int64_t> res(len);
        for (int i = 0; i < len; i++)
            res[i] = V[i + pos] + V[i + len + pos];
        return res;
    }

    static std::vector<int64_t> karatsubaMultiply(const std::vector<int64_t>& U, const std::vector<int64_t>& V, int pos, int len) {
        std::vector<int64_t> res(len << 1);
        if (len <= karatsubaMinimalSize) {
            for (int i = 0; i < len; i++)
                for (int j = 0; j < len; j++)
                    res[i + j] += U[i + pos] * V[j + pos];
            return res;
        }
        int k = len >> 1;
        std::vector<int64_t> u1v1 = karatsubaMultiply(U, V, pos, k);
        std::vector<int64_t> u2v2 = karatsubaMultiply(U, V, pos+k, k);
        std::vector<int64_t> usum = karatsubaSum(U, pos, k);
        std::vector<int64_t> vsum = karatsubaSum(V, pos, k);
        std::vector<int64_t> usum_vsum = karatsubaMultiply(usum, vsum, 0, k);
        for (int i = 0; i < len; i++) {
            res[i] += u1v1[i];
            res[i + len] += u2v2[i];
            res[i + k] += usum_vsum[i] - u1v1[i] - u2v2[i];
        }
        return res;
    }

    std::pair<bigint, bigint> div_mod(const bigint& o) const {
        assert(!o.is0() && "Divide by zero");
        std::pair<bigint, bigint> res;
        if (std::ssize(o.d) == 1) {
            res = {*this / o.d[0], *this % o.d[0]};
            return res;
        }
        const int norm = _mod / (o.d.back() + 1);
        const bigint a = *this * norm;
        const bigint b = o * norm;
        const int sz_a = std::ssize(a.d);
        const int sz_b = std::ssize(b.d);
        bigint q, r; q.d.resize(sz_a);
        for (int i = sz_a-1; i >= 0; i--) {
            r *= _mod; r += a.d[i];
            int s1 = std::ssize(r.d) <= sz_b ? 0 : r.d[sz_b];
            int s2 = std::ssize(r.d) <= sz_b-1 ? 0 : r.d[sz_b-1];
            int _d = (1LL * _mod * s1 + s2) / b.d.back();
            auto temp = b * _d;
            while (r < temp)
                r += b, --_d;
            r -= temp;
            q.d[i] = _d;
        }
        q.sign = a.sign * b.sign; r.sign = a.sign;
        q.normalize(); res = {std::move(q), r /= norm};
        return res;
    }

    friend bigint gcd(bigint A, bigint B) {
        while (!B.is0()) {
            A %= B;
            std::swap(A, B);
        }
        return A;
    }
};

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int n;
    std::cin >> n;
    std::vector<int> cnt;
    std::vector<bigint<>> a(n), b;
    for (auto &x : a)
        std::cin >> x;

    std::ranges::sort(a);
    for (int i = 0, j = 0; i < n; i = j) {
        for (; j < n and a[i] == a[j]; j++);
        cnt.push_back(j - i);
        b.push_back(a[i]);
    }

    n = b.size();
    auto inf = bigint<>('1' + std::string(1000, '0'));

    int ans = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            auto x = b[i] * b[j];
            if (x > inf) break;
            int lo = 0, hi = n - 1;
            while (lo <= hi) {
                auto m = std::midpoint(lo, hi);
                b[m] < x ? lo = m + 1 : hi = m - 1;
            }
            if (lo < n and b[lo] == x)
                ans += cnt[i] * cnt[j] * cnt[lo];
        }
    }

    std::cout << ans << '\n';
}

Submission Info

Submission Time
Task F - Product Equality
User the_hyp0cr1t3
Language C++ 20 (gcc 12.2)
Score 0
Code Size 13659 Byte
Status TLE
Exec Time 2210 ms
Memory 4600 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 0 / 550
Status
AC × 3
AC × 50
TLE × 30
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
All hack_01.txt, hack_02.txt, hack_03.txt, hack_04.txt, hack_05.txt, hand_01.txt, sample_01.txt, sample_02.txt, sample_03.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt, test_28.txt, test_29.txt, test_30.txt, test_31.txt, test_32.txt, test_33.txt, test_34.txt, test_35.txt, test_36.txt, test_37.txt, test_38.txt, test_39.txt, test_40.txt, test_41.txt, test_42.txt, test_43.txt, test_44.txt, test_45.txt, test_46.txt, test_47.txt, test_48.txt, test_49.txt, test_50.txt, test_51.txt, test_52.txt, test_53.txt, test_54.txt, test_55.txt, test_56.txt, test_57.txt, test_58.txt, test_59.txt, test_60.txt, test_61.txt, test_62.txt, test_63.txt, test_64.txt, test_65.txt, test_66.txt, test_67.txt, test_68.txt, test_69.txt, test_70.txt, test_71.txt
Case Name Status Exec Time Memory
hack_01.txt AC 28 ms 4488 KiB
hack_02.txt AC 28 ms 4472 KiB
hack_03.txt AC 51 ms 4452 KiB
hack_04.txt AC 52 ms 4524 KiB
hack_05.txt AC 50 ms 4600 KiB
hand_01.txt AC 2 ms 3512 KiB
sample_01.txt AC 1 ms 3516 KiB
sample_02.txt AC 1 ms 3448 KiB
sample_03.txt AC 1 ms 3444 KiB
test_01.txt AC 1 ms 3500 KiB
test_02.txt AC 1 ms 3504 KiB
test_03.txt AC 186 ms 3636 KiB
test_04.txt AC 187 ms 3564 KiB
test_05.txt AC 1 ms 3532 KiB
test_06.txt AC 68 ms 3620 KiB
test_07.txt AC 165 ms 3624 KiB
test_08.txt AC 188 ms 3640 KiB
test_09.txt AC 186 ms 3768 KiB
test_10.txt AC 1 ms 3480 KiB
test_11.txt AC 71 ms 3544 KiB
test_12.txt AC 164 ms 3700 KiB
test_13.txt AC 293 ms 3700 KiB
test_14.txt AC 629 ms 3600 KiB
test_15.txt TLE 2207 ms 3472 KiB
test_16.txt TLE 2207 ms 3700 KiB
test_17.txt TLE 2207 ms 3852 KiB
test_18.txt AC 141 ms 3496 KiB
test_19.txt AC 291 ms 3636 KiB
test_20.txt AC 622 ms 3652 KiB
test_21.txt TLE 2207 ms 3516 KiB
test_22.txt TLE 2207 ms 3608 KiB
test_23.txt TLE 2207 ms 3852 KiB
test_24.txt AC 150 ms 3620 KiB
test_25.txt TLE 2207 ms 3552 KiB
test_26.txt TLE 2207 ms 3736 KiB
test_27.txt AC 1053 ms 3636 KiB
test_28.txt TLE 2207 ms 3624 KiB
test_29.txt TLE 2207 ms 3624 KiB
test_30.txt AC 1015 ms 3692 KiB
test_31.txt TLE 2207 ms 3580 KiB
test_32.txt TLE 2207 ms 3568 KiB
test_33.txt AC 255 ms 3668 KiB
test_34.txt TLE 2207 ms 3608 KiB
test_35.txt TLE 2210 ms 3652 KiB
test_36.txt AC 1042 ms 3640 KiB
test_37.txt TLE 2207 ms 3616 KiB
test_38.txt TLE 2207 ms 3552 KiB
test_39.txt AC 739 ms 3672 KiB
test_40.txt AC 1 ms 3508 KiB
test_41.txt AC 1 ms 3440 KiB
test_42.txt AC 1 ms 3480 KiB
test_43.txt TLE 2207 ms 3484 KiB
test_44.txt TLE 2207 ms 3596 KiB
test_45.txt TLE 2207 ms 3516 KiB
test_46.txt TLE 2207 ms 3660 KiB
test_47.txt TLE 2207 ms 3696 KiB
test_48.txt TLE 2207 ms 3612 KiB
test_49.txt TLE 2207 ms 3784 KiB
test_50.txt TLE 2207 ms 3804 KiB
test_51.txt TLE 2207 ms 3804 KiB
test_52.txt AC 1264 ms 3956 KiB
test_53.txt AC 442 ms 3760 KiB
test_54.txt AC 72 ms 3784 KiB
test_55.txt TLE 2207 ms 3708 KiB
test_56.txt TLE 2207 ms 3776 KiB
test_57.txt AC 811 ms 3864 KiB
test_58.txt AC 451 ms 4032 KiB
test_59.txt AC 59 ms 3740 KiB
test_60.txt TLE 2207 ms 3840 KiB
test_61.txt AC 1618 ms 3916 KiB
test_62.txt AC 881 ms 3860 KiB
test_63.txt AC 503 ms 3896 KiB
test_64.txt AC 71 ms 3840 KiB
test_65.txt TLE 2207 ms 3808 KiB
test_66.txt AC 1931 ms 4020 KiB
test_67.txt AC 847 ms 3884 KiB
test_68.txt AC 495 ms 3908 KiB
test_69.txt AC 73 ms 3792 KiB
test_70.txt TLE 2207 ms 3648 KiB
test_71.txt AC 1720 ms 3988 KiB