1 条题解

  • 0
    @ 2023-5-2 9:13:40

    手写高精

    实际上只用写 (高精x低精) 和 (高精+=高精)

    #include <bits/stdc++.h>
    using namespace std;
    int MAXLEN = 10000;
    int n, m;
    vector<int> a, b;
    // now*=x (x!=0)
    void mul(vector<int> &now, int x)
    {
        // 乘
        for (int i = 0; i < now.size(); i++)
            now[i] *= x;
        // 进位
        for (int i = 1; i < now.size(); i++)
        {
            now[i] += now[i - 1] / 10;
            now[i - 1] %= 10;
        }
        while (now.back() >= 10)
        {
            now.push_back(now.back() / 10);
            now[now.size() - 2] %= 10;
        }
    }
    // a+=b
    void add(vector<int> &a, vector<int> &b)
    {
        // 补位
        while (a.size() < b.size())
            a.push_back(0);
        // 相加
        for (int i = 0; i < b.size(); i++)
            a[i] += b[i];
        // 进位
        for (int i = 1; i < a.size(); i++)
        {
            a[i] += a[i - 1] / 10;
            a[i - 1] %= 10;
        }
        while (a.back() >= 10)
        {
            a.push_back(a.back() / 10);
            a[a.size() - 2] %= 10;
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n >> m;
        a.push_back(1); // a=1
        b.push_back(1); // b=1
        // A(n,n) * A(n+1,2) * A(n+3,m)
        for (int i = 1; i <= n; i++)
            mul(a, i);
        mul(a, (n + 1) * n);
        for (int i = n + 3; i >= n + 3 - m + 1; i--)
            mul(a, i);
        // A(n,n) * A(n+1,1) * A(2,2) * A(m,1) * A(n+2,m-1)
        for (int i = 1; i <= n; i++)
            mul(b, i);
        mul(b, (n + 1) * 2 * m);
        for (int i = n + 2; i >= (n + 2) - (m - 1) + 1; i--)
            mul(b, i);
        // get ans
        add(a, b);
        for (int i = a.size() - 1; i >= 0; i--)
            cout << a[i];
        cout << "\n";
        return 0;
    }
    
    /*
    高精度时能排列就别组合,毕竟排列数可以只涉及乘法,没有除法
    
    老师中间有男生:男生排好后挑两个空位放老师,然后再在空位里放女生
    A(n,n) * A(n+1,2) * A(n+3,m)
    
    老师中间没男生:两老师+一女生打包
    A(n,n) * A(n+1,1) * A(2,2) * A(m,1) * A(n+2,m-1)
    */
    

    使用高精度模板

    #include <bits/stdc++.h>
    using namespace std;
    
    struct BigIntTiny
    {
        int sign;
        std::vector<int> v;
    
        BigIntTiny() : sign(1) {}
        BigIntTiny(const std::string &s) { *this = s; }
        BigIntTiny(int v)
        {
            char buf[21];
            sprintf(buf, "%d", v);
            *this = buf;
        }
        void zip(int unzip)
        {
            if (unzip == 0)
            {
                for (int i = 0; i < (int)v.size(); i++)
                    v[i] = get_pos(i * 4) + get_pos(i * 4 + 1) * 10 + get_pos(i * 4 + 2) * 100 + get_pos(i * 4 + 3) * 1000;
            }
            else
                for (int i = (v.resize(v.size() * 4), (int)v.size() - 1), a; i >= 0; i--)
                    a = (i % 4 >= 2) ? v[i / 4] / 100 : v[i / 4] % 100, v[i] = (i & 1) ? a / 10 : a % 10;
            setsign(1, 1);
        }
        int get_pos(unsigned pos) const { return pos >= v.size() ? 0 : v[pos]; }
        BigIntTiny &setsign(int newsign, int rev)
        {
            for (int i = (int)v.size() - 1; i > 0 && v[i] == 0; i--)
                v.erase(v.begin() + i);
            sign = (v.size() == 0 || (v.size() == 1 && v[0] == 0)) ? 1 : (rev ? newsign * sign : newsign);
            return *this;
        }
        std::string to_str() const
        {
            BigIntTiny b = *this;
            std::string s;
            for (int i = (b.zip(1), 0); i < (int)b.v.size(); ++i)
                s += char(*(b.v.rbegin() + i) + '0');
            return (sign < 0 ? "-" : "") + (s.empty() ? std::string("0") : s);
        }
        bool absless(const BigIntTiny &b) const
        {
            if (v.size() != b.v.size())
                return v.size() < b.v.size();
            for (int i = (int)v.size() - 1; i >= 0; i--)
                if (v[i] != b.v[i])
                    return v[i] < b.v[i];
            return false;
        }
        BigIntTiny operator-() const
        {
            BigIntTiny c = *this;
            c.sign = (v.size() > 1 || v[0]) ? -c.sign : 1;
            return c;
        }
        BigIntTiny &operator=(const std::string &s)
        {
            if (s[0] == '-')
                *this = s.substr(1);
            else
            {
                for (int i = (v.clear(), 0); i < (int)s.size(); ++i)
                    v.push_back(*(s.rbegin() + i) - '0');
                zip(0);
            }
            return setsign(s[0] == '-' ? -1 : 1, sign = 1);
        }
        bool operator<(const BigIntTiny &b) const
        {
            return sign != b.sign ? sign < b.sign : (sign == 1 ? absless(b) : b.absless(*this));
        }
        bool operator==(const BigIntTiny &b) const { return v == b.v && sign == b.sign; }
        BigIntTiny &operator+=(const BigIntTiny &b)
        {
            if (sign != b.sign)
                return *this = (*this) - -b;
            v.resize(std::max(v.size(), b.v.size()) + 1);
            for (int i = 0, carry = 0; i < (int)b.v.size() || carry; i++)
            {
                carry += v[i] + b.get_pos(i);
                v[i] = carry % 10000, carry /= 10000;
            }
            return setsign(sign, 0);
        }
        BigIntTiny operator+(const BigIntTiny &b) const
        {
            BigIntTiny c = *this;
            return c += b;
        }
        void add_mul(const BigIntTiny &b, int mul)
        {
            v.resize(std::max(v.size(), b.v.size()) + 2);
            for (int i = 0, carry = 0; i < (int)b.v.size() || carry; i++)
            {
                carry += v[i] + b.get_pos(i) * mul;
                v[i] = carry % 10000, carry /= 10000;
            }
        }
        BigIntTiny operator-(const BigIntTiny &b) const
        {
            if (sign != b.sign)
                return (*this) + -b;
            if (absless(b))
                return -(b - *this);
            BigIntTiny c;
            for (int i = 0, borrow = 0; i < (int)v.size(); i++)
            {
                borrow += v[i] - b.get_pos(i);
                c.v.push_back(borrow);
                c.v.back() -= 10000 * (borrow >>= 31);
            }
            return c.setsign(sign, 0);
        }
        BigIntTiny operator*(const BigIntTiny &b) const
        {
            if (b < *this)
                return b * *this;
            BigIntTiny c, d = b;
            for (int i = 0; i < (int)v.size(); i++, d.v.insert(d.v.begin(), 0))
                c.add_mul(d, v[i]);
            return c.setsign(sign * b.sign, 0);
        }
        BigIntTiny operator/(const BigIntTiny &b) const
        {
            BigIntTiny c, d;
            d.v.resize(v.size());
            double db = 1.0 / (b.v.back() + (b.get_pos((unsigned)b.v.size() - 2) / 1e4) +
                               (b.get_pos((unsigned)b.v.size() - 3) + 1) / 1e8);
            for (int i = (int)v.size() - 1; i >= 0; i--)
            {
                c.v.insert(c.v.begin(), v[i]);
                int m = (int)((c.get_pos((int)b.v.size()) * 10000 + c.get_pos((int)b.v.size() - 1)) * db);
                c = c - b * m, d.v[i] += m;
                while (!(c < b))
                    c = c - b, d.v[i] += 1;
            }
            return d.setsign(sign * b.sign, 0);
        }
        BigIntTiny operator%(const BigIntTiny &b) const { return *this - *this / b * b; }
        bool operator>(const BigIntTiny &b) const { return b < *this; }
        bool operator<=(const BigIntTiny &b) const { return !(b < *this); }
        bool operator>=(const BigIntTiny &b) const { return !(*this < b); }
        bool operator!=(const BigIntTiny &b) const { return !(*this == b); }
    };
    
    int n, m;
    BigIntTiny ans1, ans2, ans;
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n >> m;
        // A(n,n) * A(n+1,2) * A(n+3,m)
        ans1 = 1;
        for (int i = 1; i <= n; i++)
            ans1 = ans1 * i;
        ans1 = ans1 * ((n + 1) * n);
        for (int i = n + 3; i >= n + 3 - m + 1; i--)
            ans1 = ans1 * i;
        // cout << ans1.to_str() << "\n";
        // A(n,n) * A(n+1,1) * A(2,2) * A(m,1) * A(n+2,m-1)
        ans2 = 1;
        for (int i = 1; i <= n; i++)
            ans2 = ans2 * i;
        ans2 = ans2 * ((n + 1) * 2 * m);
        for (int i = n + 2; i >= (n + 2) - (m - 1) + 1; i--)
            ans2 = ans2 * i;
        // cout << ans2.to_str() << "\n";
        // get ans
        ans1 += ans2;
        cout << ans1.to_str() << "\n";
        return 0;
    }
    
    /*
    高精度时能排列就别组合,毕竟排列数可以只涉及乘法,没有除法
    
    老师中间有男生:男生排好后挑两个空位放老师,然后再在空位里放女生
    A(n,n) * A(n+1,2) * A(n+3,m)
    
    老师中间没男生:两老师+一女生打包
    A(n,n) * A(n+1,1) * A(2,2) * A(m,1) * A(n+2,m-1)
    */
    
    • 1

    信息

    ID
    1276
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    28
    已通过
    13
    上传者