Advertisement
NickAndNick

Pow for BigInteger

Mar 26th, 2024
808
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.68 KB | Software | 0 0
  1. #include <fstream>
  2. #include <iomanip>
  3. #include <iostream>
  4. #include <sstream>
  5. #include <string>
  6. #include <vector>
  7.  
  8. using namespace std;
  9.  
  10. class BigInteger {
  11. public:
  12.     BigInteger() : is_negative(false) {
  13.         digits.push_back(0);
  14.     }
  15.  
  16.     BigInteger(string str) {
  17.         if (str.length() == 0) is_negative = false;
  18.         else {
  19.             if (str[0] == '-') {
  20.                 str = str.substr(1);
  21.                 is_negative = true;
  22.             } else is_negative = false;
  23.             for (auto i = static_cast<long long>(str.length()); i > 0; i -= 9) {
  24.                 if (i < 9) digits.push_back(atoi(str.substr(0, i).c_str()));
  25.                 else digits.push_back(atoi(str.substr(i - 9, 9).c_str()));
  26.             }
  27.             remove_leading_zeros();
  28.         }
  29.     }
  30.  
  31.     BigInteger(signed long long value) {
  32.         if (value < 0) {
  33.             is_negative = true;
  34.             value = -value;
  35.         } else is_negative = false;
  36.         do {
  37.             digits.push_back(value % base);
  38.             value /= base;
  39.         } while (value != 0);
  40.     }
  41.  
  42.     BigInteger(unsigned long long value) {
  43.         is_negative = false;
  44.         do {
  45.             digits.push_back(value % base);
  46.             value /= base;
  47.         } while (value != 0);
  48.     }
  49.  
  50.     operator string() const {
  51.         stringstream ss;
  52.         ss << *this;
  53.         return ss.str();
  54.     }
  55.  
  56.     const BigInteger operator+() const {
  57.         return BigInteger(*this);
  58.     }
  59.  
  60.     const BigInteger operator-() const {
  61.         BigInteger copy(*this);
  62.         copy.is_negative = !copy.is_negative;
  63.         return copy;
  64.     }
  65.  
  66.     void operator*=(const BigInteger& bi) {
  67.         *this = *this * bi;
  68.     }
  69.  
  70.     void operator/=(const BigInteger& bi) {
  71.         *this = *this / bi;
  72.     }
  73.  
  74.     const BigInteger pow(BigInteger bi) const {
  75.         BigInteger a(*this), result(1LL);
  76.         while (bi != 0LL) {
  77.             if (bi.odd()) result *= a;
  78.             a *= a;
  79.             bi /= 2LL;
  80.         }
  81.         return result;
  82.     }
  83. private:
  84.     class DidisionByZero : public exception {};
  85.     static const auto base = 1000000000;
  86.     vector<int> digits;
  87.     bool is_negative;
  88.  
  89.     void remove_leading_zeros() {
  90.         while (digits.size() > 1 && digits.back() == 0) digits.pop_back();
  91.         if (digits.size() == 1 && digits[0] == 0) is_negative = false;
  92.     }
  93.  
  94.     void shift_right() {
  95.         if (digits.size() == 0) {
  96.             digits.push_back(0);
  97.             return;
  98.         }
  99.         digits.push_back(digits[digits.size() - 1]);
  100.         for (size_t i = digits.size() - 2; i > 0; --i) digits[i] = digits[i - 1];
  101.         digits[0] = 0;
  102.     }
  103.  
  104.     bool odd() const {
  105.         if (digits.size() == 0) return false;
  106.         return digits[0] & 1;
  107.     }
  108.  
  109.     bool even() const {
  110.         return !this->odd();
  111.     }
  112.  
  113.     friend bool operator==(const BigInteger& a, const BigInteger& b) {
  114.         if (a.is_negative != b.is_negative) return false;
  115.         if (a.digits.empty()) {
  116.             if (b.digits.empty() || (b.digits.size() == 1 && b.digits[0] == 0)) return true;
  117.             else return false;
  118.         }
  119.         if (b.digits.empty()) {
  120.             if (a.digits.size() == 1 && a.digits[0] == 0) return true;
  121.             else return false;
  122.         }
  123.         if (a.digits.size() != b.digits.size()) return false;
  124.         for (size_t i = 0; i < a.digits.size(); ++i) if (a.digits[i] != b.digits[i]) return false;
  125.         return true;
  126.     }
  127.  
  128.     friend bool operator <(const BigInteger& a, const BigInteger& b) {
  129.         if (a == b) return false;
  130.         if (a.is_negative) {
  131.             if (b.is_negative) return ((-b) < (-a));
  132.             else return true;
  133.         }
  134.         else if (b.is_negative) return false;
  135.         else {
  136.             if (a.digits.size() != b.digits.size()) {
  137.                 return a.digits.size() < b.digits.size();
  138.             } else {
  139.                 for (long long i = a.digits.size() - 1; i >= 0; --i) {
  140.                     if (a.digits[i] != b.digits[i]) return a.digits[i] < b.digits[i];
  141.                 }
  142.                 return false;
  143.             }
  144.         }
  145.     }
  146.  
  147.     friend bool operator<=(const BigInteger& a, const BigInteger& b) {
  148.         return (a < b || a == b);
  149.     }
  150.  
  151.     friend bool operator!=(const BigInteger& a, const BigInteger& b) {
  152.         return !(a == b);
  153.     }
  154.  
  155.     friend bool operator>(const BigInteger& a, const BigInteger& b) {
  156.         return !(a <= b);
  157.     }
  158.  
  159.     friend bool operator>=(const BigInteger& a, const BigInteger& b) {
  160.         return !(a < b);
  161.     }
  162.  
  163.     friend const BigInteger operator+(BigInteger a, const BigInteger& b) {
  164.         if (a.is_negative) {
  165.             if (b.is_negative) return -(-a + (-b));
  166.             else return b - (-a);
  167.         }
  168.         else if (b.is_negative) return a - (-b);
  169.         auto transfer = 0;
  170.         for (size_t i = 0; i < std::max(a.digits.size(), b.digits.size()) || transfer != 0; ++i) {
  171.             if (i == a.digits.size()) a.digits.push_back(0);
  172.             a.digits[i] += transfer + (i < b.digits.size() ? b.digits[i] : 0);
  173.             transfer = a.digits[i] >= BigInteger::base;
  174.             if (transfer != 0) a.digits[i] -= BigInteger::base;
  175.         }
  176.         return a;
  177.     }
  178.  
  179.     friend const BigInteger operator-(BigInteger a, const BigInteger& b) {
  180.         if (b.is_negative) return a + (-b);
  181.         else if (a.is_negative) return -(-a + b);
  182.         else if (a < b) return -(b - a);
  183.         auto transfer = 0;
  184.         for (size_t i = 0; i < b.digits.size() || transfer != 0; ++i) {
  185.             a.digits[i] -= transfer + (i < b.digits.size() ? b.digits[i] : 0);
  186.             transfer = a.digits[i] < 0;
  187.             if (transfer != 0) a.digits[i] += BigInteger::base;
  188.         }
  189.         a.remove_leading_zeros();
  190.         return a;
  191.     }
  192.  
  193.     friend const BigInteger operator*(const BigInteger& a, const BigInteger& b) {
  194.         BigInteger result;
  195.         result.digits.resize(a.digits.size() + b.digits.size());
  196.         for (size_t i = 0; i < a.digits.size(); ++i) {
  197.             auto transfer = 0;
  198.             for (size_t j = 0; j < b.digits.size() || transfer != 0; ++j) {
  199.                 auto current = result.digits[i + j] +
  200.                     a.digits[i] * 1LL * (j < b.digits.size() ? b.digits[j] : 0) + transfer;
  201.                 result.digits[i + j] = static_cast<int>(current % BigInteger::base);
  202.                 transfer = static_cast<int>(current / BigInteger::base);
  203.             }
  204.         }
  205.         result.is_negative = a.is_negative != b.is_negative;
  206.         result.remove_leading_zeros();
  207.         return result;
  208.     }
  209.  
  210.     friend const BigInteger operator/(const BigInteger& a, const BigInteger& b) {
  211.         if (b == 0LL) throw BigInteger::DidisionByZero();
  212.         BigInteger bi = b;
  213.         bi.is_negative = false;
  214.         BigInteger result, current;
  215.         result.digits.resize(a.digits.size());
  216.         for (long long i = static_cast<long long>(a.digits.size()) - 1; i >= 0; --i) {
  217.             current.shift_right();
  218.             current.digits[0] = a.digits[i];
  219.             current.remove_leading_zeros();
  220.             long long x = 0, l = 0, r = BigInteger::base;
  221.             while (l <= r) {
  222.                 auto m = (l + r) / 2;
  223.                 BigInteger tmp = bi * m;
  224.                 if (tmp <= current) {
  225.                     x = m;
  226.                     l = m + 1;
  227.                 }
  228.                 else r = m - 1;
  229.             }
  230.             result.digits[i] = x;
  231.             current = current - bi * x;
  232.         }
  233.         result.is_negative = a.is_negative != b.is_negative;
  234.         result.remove_leading_zeros();
  235.         return result;
  236.     }
  237.  
  238.     friend ostream& operator<<(ostream& out, const BigInteger& bi) {
  239.         if (bi.digits.empty()) out << 0;
  240.         else {
  241.             if (bi.is_negative) out << '-';
  242.             out << bi.digits.back();
  243.             char old_fill = out.fill('0');
  244.             for (auto i = static_cast<long long>(bi.digits.size()) - 2; i >= 0; --i) {
  245.                 out << std::setw(9) << bi.digits[i];
  246.             }
  247.             out.fill(old_fill);
  248.         }
  249.         return out;
  250.     }
  251.  
  252.     friend istream& operator>>(istream& inp, BigInteger& bi) {
  253.         string num;
  254.         inp >> num;
  255.         bi = BigInteger(num);
  256.         return inp;
  257.     }
  258. };
  259.  
  260. int main() {
  261.     string input{ R"(C:\Users\student\Desktop\ConsoleApplication1\input.txt)" };
  262.     string output{ R"(C:\Users\student\Desktop\ConsoleApplication1\output.txt)" };
  263.     ifstream inp(input);
  264.     ofstream out(output);
  265.     if (inp.is_open() && out.is_open()) {
  266.         BigInteger n;
  267.         BigInteger p;
  268.         inp >> n >> p;
  269.         out << n.pow(p);
  270.     }
  271.     inp.is_open() ? inp.close() : void();
  272.     out.is_open() ? out.close() : void();
  273. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement