Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <fstream>
- #include <iomanip>
- #include <iostream>
- #include <sstream>
- #include <string>
- #include <vector>
- using namespace std;
- class BigInteger {
- public:
- BigInteger() : is_negative(false) {
- digits.push_back(0);
- }
- BigInteger(string str) {
- if (str.length() == 0) is_negative = false;
- else {
- if (str[0] == '-') {
- str = str.substr(1);
- is_negative = true;
- } else is_negative = false;
- for (auto i = static_cast<long long>(str.length()); i > 0; i -= 9) {
- if (i < 9) digits.push_back(atoi(str.substr(0, i).c_str()));
- else digits.push_back(atoi(str.substr(i - 9, 9).c_str()));
- }
- remove_leading_zeros();
- }
- }
- BigInteger(signed long long value) {
- if (value < 0) {
- is_negative = true;
- value = -value;
- } else is_negative = false;
- do {
- digits.push_back(value % base);
- value /= base;
- } while (value != 0);
- }
- BigInteger(unsigned long long value) {
- is_negative = false;
- do {
- digits.push_back(value % base);
- value /= base;
- } while (value != 0);
- }
- operator string() const {
- stringstream ss;
- ss << *this;
- return ss.str();
- }
- const BigInteger operator+() const {
- return BigInteger(*this);
- }
- const BigInteger operator-() const {
- BigInteger copy(*this);
- copy.is_negative = !copy.is_negative;
- return copy;
- }
- void operator*=(const BigInteger& bi) {
- *this = *this * bi;
- }
- void operator/=(const BigInteger& bi) {
- *this = *this / bi;
- }
- const BigInteger pow(BigInteger bi) const {
- BigInteger a(*this), result(1LL);
- while (bi != 0LL) {
- if (bi.odd()) result *= a;
- a *= a;
- bi /= 2LL;
- }
- return result;
- }
- private:
- class DidisionByZero : public exception {};
- static const auto base = 1000000000;
- vector<int> digits;
- bool is_negative;
- void remove_leading_zeros() {
- while (digits.size() > 1 && digits.back() == 0) digits.pop_back();
- if (digits.size() == 1 && digits[0] == 0) is_negative = false;
- }
- void shift_right() {
- if (digits.size() == 0) {
- digits.push_back(0);
- return;
- }
- digits.push_back(digits[digits.size() - 1]);
- for (size_t i = digits.size() - 2; i > 0; --i) digits[i] = digits[i - 1];
- digits[0] = 0;
- }
- bool odd() const {
- if (digits.size() == 0) return false;
- return digits[0] & 1;
- }
- bool even() const {
- return !this->odd();
- }
- friend bool operator==(const BigInteger& a, const BigInteger& b) {
- if (a.is_negative != b.is_negative) return false;
- if (a.digits.empty()) {
- if (b.digits.empty() || (b.digits.size() == 1 && b.digits[0] == 0)) return true;
- else return false;
- }
- if (b.digits.empty()) {
- if (a.digits.size() == 1 && a.digits[0] == 0) return true;
- else return false;
- }
- if (a.digits.size() != b.digits.size()) return false;
- for (size_t i = 0; i < a.digits.size(); ++i) if (a.digits[i] != b.digits[i]) return false;
- return true;
- }
- friend bool operator <(const BigInteger& a, const BigInteger& b) {
- if (a == b) return false;
- if (a.is_negative) {
- if (b.is_negative) return ((-b) < (-a));
- else return true;
- }
- else if (b.is_negative) return false;
- else {
- if (a.digits.size() != b.digits.size()) {
- return a.digits.size() < b.digits.size();
- } else {
- for (long long i = a.digits.size() - 1; i >= 0; --i) {
- if (a.digits[i] != b.digits[i]) return a.digits[i] < b.digits[i];
- }
- return false;
- }
- }
- }
- friend bool operator<=(const BigInteger& a, const BigInteger& b) {
- return (a < b || a == b);
- }
- friend bool operator!=(const BigInteger& a, const BigInteger& b) {
- return !(a == b);
- }
- friend bool operator>(const BigInteger& a, const BigInteger& b) {
- return !(a <= b);
- }
- friend bool operator>=(const BigInteger& a, const BigInteger& b) {
- return !(a < b);
- }
- friend const BigInteger operator+(BigInteger a, const BigInteger& b) {
- if (a.is_negative) {
- if (b.is_negative) return -(-a + (-b));
- else return b - (-a);
- }
- else if (b.is_negative) return a - (-b);
- auto transfer = 0;
- for (size_t i = 0; i < std::max(a.digits.size(), b.digits.size()) || transfer != 0; ++i) {
- if (i == a.digits.size()) a.digits.push_back(0);
- a.digits[i] += transfer + (i < b.digits.size() ? b.digits[i] : 0);
- transfer = a.digits[i] >= BigInteger::base;
- if (transfer != 0) a.digits[i] -= BigInteger::base;
- }
- return a;
- }
- friend const BigInteger operator-(BigInteger a, const BigInteger& b) {
- if (b.is_negative) return a + (-b);
- else if (a.is_negative) return -(-a + b);
- else if (a < b) return -(b - a);
- auto transfer = 0;
- for (size_t i = 0; i < b.digits.size() || transfer != 0; ++i) {
- a.digits[i] -= transfer + (i < b.digits.size() ? b.digits[i] : 0);
- transfer = a.digits[i] < 0;
- if (transfer != 0) a.digits[i] += BigInteger::base;
- }
- a.remove_leading_zeros();
- return a;
- }
- friend const BigInteger operator*(const BigInteger& a, const BigInteger& b) {
- BigInteger result;
- result.digits.resize(a.digits.size() + b.digits.size());
- for (size_t i = 0; i < a.digits.size(); ++i) {
- auto transfer = 0;
- for (size_t j = 0; j < b.digits.size() || transfer != 0; ++j) {
- auto current = result.digits[i + j] +
- a.digits[i] * 1LL * (j < b.digits.size() ? b.digits[j] : 0) + transfer;
- result.digits[i + j] = static_cast<int>(current % BigInteger::base);
- transfer = static_cast<int>(current / BigInteger::base);
- }
- }
- result.is_negative = a.is_negative != b.is_negative;
- result.remove_leading_zeros();
- return result;
- }
- friend const BigInteger operator/(const BigInteger& a, const BigInteger& b) {
- if (b == 0LL) throw BigInteger::DidisionByZero();
- BigInteger bi = b;
- bi.is_negative = false;
- BigInteger result, current;
- result.digits.resize(a.digits.size());
- for (long long i = static_cast<long long>(a.digits.size()) - 1; i >= 0; --i) {
- current.shift_right();
- current.digits[0] = a.digits[i];
- current.remove_leading_zeros();
- long long x = 0, l = 0, r = BigInteger::base;
- while (l <= r) {
- auto m = (l + r) / 2;
- BigInteger tmp = bi * m;
- if (tmp <= current) {
- x = m;
- l = m + 1;
- }
- else r = m - 1;
- }
- result.digits[i] = x;
- current = current - bi * x;
- }
- result.is_negative = a.is_negative != b.is_negative;
- result.remove_leading_zeros();
- return result;
- }
- friend ostream& operator<<(ostream& out, const BigInteger& bi) {
- if (bi.digits.empty()) out << 0;
- else {
- if (bi.is_negative) out << '-';
- out << bi.digits.back();
- char old_fill = out.fill('0');
- for (auto i = static_cast<long long>(bi.digits.size()) - 2; i >= 0; --i) {
- out << std::setw(9) << bi.digits[i];
- }
- out.fill(old_fill);
- }
- return out;
- }
- friend istream& operator>>(istream& inp, BigInteger& bi) {
- string num;
- inp >> num;
- bi = BigInteger(num);
- return inp;
- }
- };
- int main() {
- string input{ R"(C:\Users\student\Desktop\ConsoleApplication1\input.txt)" };
- string output{ R"(C:\Users\student\Desktop\ConsoleApplication1\output.txt)" };
- ifstream inp(input);
- ofstream out(output);
- if (inp.is_open() && out.is_open()) {
- BigInteger n;
- BigInteger p;
- inp >> n >> p;
- out << n.pow(p);
- }
- inp.is_open() ? inp.close() : void();
- out.is_open() ? out.close() : void();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement