1 条题解
-
0
手写高精
实际上只用写 (高精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
- 上传者