Advertisement
arujbansal

Untitled

Sep 8th, 2021
1,085
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.56 KB | None | 0 0
  1. // By: https://codeforces.com/profile/neal
  2. // https://codeforces.com/contest/1499/submission/110349694
  3. template<const int &MOD>
  4. struct _m_int {
  5.     int val;
  6.  
  7.     _m_int(int64_t v = 0) {
  8.         if (v < 0) v = v % MOD + MOD;
  9.         if (v >= MOD) v %= MOD;
  10.         val = int(v);
  11.     }
  12.  
  13.     _m_int(uint64_t v) {
  14.         if (v >= MOD) v %= MOD;
  15.         val = int(v);
  16.     }
  17.  
  18.     _m_int(int v) : _m_int(int64_t(v)) {}
  19.     _m_int(unsigned v) : _m_int(uint64_t(v)) {}
  20.  
  21.     explicit operator int() const { return val; }
  22.     explicit operator unsigned() const { return val; }
  23.     explicit operator int64_t() const { return val; }
  24.     explicit operator uint64_t() const { return val; }
  25.     explicit operator double() const { return val; }
  26.     explicit operator long double() const { return val; }
  27.  
  28.     _m_int& operator+=(const _m_int &other) {
  29.         val -= MOD - other.val;
  30.         if (val < 0) val += MOD;
  31.         return *this;
  32.     }
  33.  
  34.     _m_int& operator-=(const _m_int &other) {
  35.         val -= other.val;
  36.         if (val < 0) val += MOD;
  37.         return *this;
  38.     }
  39.  
  40.     static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
  41. #if !defined(_WIN32) || defined(_WIN64)
  42.         return unsigned(x % m);
  43. #endif
  44.         // Optimized mod for Codeforces 32-bit machines.
  45.         // x must be less than 2^32 * m for this to work, so that x / m fits in an unsigned 32-bit int.
  46.         unsigned x_high = unsigned(x >> 32), x_low = unsigned(x);
  47.         unsigned quot, rem;
  48.         asm("divl %4\n"
  49.             : "=a" (quot), "=d" (rem)
  50.             : "d" (x_high), "a" (x_low), "r" (m));
  51.         return rem;
  52.     }
  53.  
  54.     _m_int& operator*=(const _m_int &other) {
  55.         val = fast_mod(uint64_t(val) * other.val);
  56.         return *this;
  57.     }
  58.  
  59.     _m_int& operator/=(const _m_int &other) {
  60.         return *this *= other.inv();
  61.     }
  62.  
  63.     friend _m_int operator+(const _m_int &a, const _m_int &b) { return _m_int(a) += b; }
  64.     friend _m_int operator-(const _m_int &a, const _m_int &b) { return _m_int(a) -= b; }
  65.     friend _m_int operator*(const _m_int &a, const _m_int &b) { return _m_int(a) *= b; }
  66.     friend _m_int operator/(const _m_int &a, const _m_int &b) { return _m_int(a) /= b; }
  67.  
  68.     _m_int& operator++() {
  69.         val = val == MOD - 1 ? 0 : val + 1;
  70.         return *this;
  71.     }
  72.  
  73.     _m_int& operator--() {
  74.         val = val == 0 ? MOD - 1 : val - 1;
  75.         return *this;
  76.     }
  77.  
  78.     _m_int operator++(int) { _m_int before = *this; ++*this; return before; }
  79.     _m_int operator--(int) { _m_int before = *this; --*this; return before; }
  80.  
  81.     _m_int operator-() const {
  82.         return val == 0 ? 0 : MOD - val;
  83.     }
  84.  
  85.     friend bool operator==(const _m_int &a, const _m_int &b) { return a.val == b.val; }
  86.     friend bool operator!=(const _m_int &a, const _m_int &b) { return a.val != b.val; }
  87.     friend bool operator<(const _m_int &a, const _m_int &b) { return a.val < b.val; }
  88.     friend bool operator>(const _m_int &a, const _m_int &b) { return a.val > b.val; }
  89.     friend bool operator<=(const _m_int &a, const _m_int &b) { return a.val <= b.val; }
  90.     friend bool operator>=(const _m_int &a, const _m_int &b) { return a.val >= b.val; }
  91.  
  92.     static const int SAVE_INV = int(1e6) + 5;
  93.     static _m_int save_inv[SAVE_INV];
  94.  
  95.     static void prepare_inv() {
  96.         // Make sure MOD is prime, which is necessary for the inverse algorithm below.
  97.         for (int64_t p = 2; p * p <= MOD; p += p % 2 + 1)
  98.             assert(MOD % p != 0);
  99.  
  100.         save_inv[0] = 0;
  101.         save_inv[1] = 1;
  102.  
  103.         for (int i = 2; i < SAVE_INV; i++)
  104.             save_inv[i] = save_inv[MOD % i] * (MOD - MOD / i);
  105.     }
  106.  
  107.     _m_int inv() const {
  108.         if (save_inv[1] == 0)
  109.             prepare_inv();
  110.  
  111.         if (val < SAVE_INV)
  112.             return save_inv[val];
  113.  
  114.         _m_int product = 1;
  115.         int v = val;
  116.  
  117.         while (v >= SAVE_INV) {
  118.             product *= MOD - MOD / v;
  119.             v = MOD % v;
  120.         }
  121.  
  122.         return product * save_inv[v];
  123.     }
  124.  
  125.     _m_int pow(int64_t p) const {
  126.         if (p < 0)
  127.             return inv().pow(-p);
  128.  
  129.         _m_int a = *this, result = 1;
  130.  
  131.         while (p > 0) {
  132.             if (p & 1)
  133.                 result *= a;
  134.  
  135.             p >>= 1;
  136.  
  137.             if (p > 0)
  138.                 a *= a;
  139.         }
  140.  
  141.         return result;
  142.     }
  143.  
  144.     friend ostream& operator<<(ostream &os, const _m_int &m) {
  145.         return os << m.val;
  146.     }
  147. };
  148.  
  149. template<const int &MOD> _m_int<MOD> _m_int<MOD>::save_inv[_m_int<MOD>::SAVE_INV];
  150.  
  151. const int MOD = 998244353;
  152. using mint = _m_int<MOD>;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement