Cod sursa(job #2702630)

Utilizator retrogradLucian Bicsi retrograd Data 5 februarie 2021 01:43:27
Problema Ridicare la putere in timp logaritmic Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.07 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);
}
T add(T a, T b) { a += b; if (a >= mod) a -= mod; return a; }
T sub(T a, T b) { return add(a, mod - b); }
T tomont(T x) { return mul(x, r2); }
T toreal(T x) { return reduce(x); }
T lgpow(T b, T e) {
  T r = tomont(1);
  while (e) { 
    if (e % 2) r = mul(r, b);
    b = mul(b, b); e /= 2; 
  }
  return r;
}

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