Cod sursa(job #2702629)

Utilizator retrogradLucian Bicsi retrograd Data 5 februarie 2021 01:30:30
Problema Ridicare la putere in timp logaritmic Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.39 kb
#include <bits/stdc++.h>

using namespace std;

// Set T2 such that (T2)mod * mod does not overflow.
using T = uint64_t;
using T2 = __uint128_t;
const int BITS = 8 * sizeof(T);

T mod, inv, r2;  
T reduce(T2 x) {
  T q = (T)x * inv;
  T a = (T)((x - (T2)q * mod) >> BITS);
  if (a >= mod) a += mod;
  return a;
}
T mul(T a, T b) { return reduce((T2)a * b); }
void init(T modulo) {
  mod = modulo; inv = 1; r2 = -mod % mod;
  for (int i = 1; i < BITS; i *= 2)
    inv *= 2 - mod * inv;
  for (int i = 0; i < 4; i++) 
    if ((r2 *= 2) >= mod) 
      r2 -= mod;
  for (int i = 4; i < BITS; i *= 2)
    r2 = mul(r2, r2);
}

struct ModInt {
  T x;
  ModInt(T x) : x(mul(x, r2)) {}
  ModInt ctr(T x) { 
    if (x >= mod) x -= mod;
    ModInt ret(*this); ret.x = x; return ret;
  }
  ModInt operator+(ModInt oth) { return ctr(x + oth.x); }
  ModInt operator-(ModInt oth) { return ctr(x + mod - oth.x); }
  ModInt operator*(ModInt oth) { return ctr(mul(x, oth.x)); } 
  ModInt operator/(ModInt b) { return *this * b.inv(); }
  ModInt inv() { return pow(mod - 2); }
  ModInt pow(T e) {
    if (!e) return 1;
    ModInt r = pow(e / 2); r = r * r;
    return e % 2 ? *this * r : r;
  }
  bool operator==(ModInt o) { return x == o.x; }
  T Get() { return reduce(x); }
};

int main() {
  ifstream cin("lgput.in");
  ofstream cout("lgput.out");
  init(1999999973);
  int a, b; cin >> a >> b;
  cout << ModInt(a).pow(b).Get() << endl;
}