Extended Euler's theorem [study notes]

Cushions for a long time ...

P4139 God and the correct use of the set

For \ (B \ GEQ \ varphi (P) \) , there are \ (a ^ b = a ^ {b \ mod \ \ varphi (p) \ + \ \ varphi (p)} [mod \ p] \)

Wherein \ (gcd (a, p) \) is not required, i.e. may not prime.

With this equation, \ (^ 2 ^ 2 {{{2 ^ 2 ^ 2 ^ {^ {2} {2}}}}} \% \ P \) to find the good, recursive, here index \ (2 ^ {2 ^ { 2 ^ {2 ^ {2 ^ {2}}}}} \ geq \ varphi (p) \) , then directly use the output QAQ. Recursive no more than \ (\ log \) times, so you can use recursion enough qwq.

// by Isaunoya
#include <bits/stdc++.h>
using namespace std;

#define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
#define Rep(i, x, y) for (register int i = (x); i >= (y); --i)

const int _ = 1 << 21;
struct I {
  char fin[_], *p1 = fin, *p2 = fin;
  inline char gc() {
    return (p1 == p2) && (p2 = (p1 = fin) + fread(fin, 1, _, stdin), p1 == p2) ? EOF : *p1++;
  }
  inline I& operator>>(int& x) {
    bool sign = 1;
    char c = 0;
    while (c < 48) ((c = gc()) == 45) && (sign = 0);
    x = (c & 15);
    while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
    x = sign ? x : -x;
    return *this;
  }
  inline I& operator>>(double& x) {
    bool sign = 1;
    char c = 0;
    while (c < 48) ((c = gc()) == 45) && (sign = 0);
    x = (c - 48);
    while ((c = gc()) > 47) x = x * 10 + (c - 48);
    if (c == '.') {
      double d = 1.0;
      while ((c = gc()) > 47) d = d * 0.1, x = x + (d * (c - 48));
    }
    x = sign ? x : -x;
    return *this;
  }
  inline I& operator>>(char& x) {
    do
      x = gc();
    while (isspace(x));
    return *this;
  }
  inline I& operator>>(string& s) {
    s = "";
    char c = gc();
    while (isspace(c)) c = gc();
    while (!isspace(c) && c != EOF) s += c, c = gc();
    return *this;
  }
} in;
struct O {
  char st[100], fout[_];
  signed stk = 0, top = 0;
  inline void flush() { fwrite(fout, 1, top, stdout), fflush(stdout), top = 0; }
  inline O& operator<<(int x) {
    if (top > (1 << 20)) flush();
    if (x < 0) fout[top++] = 45, x = -x;
    do
      st[++stk] = x % 10 ^ 48, x /= 10;
    while (x);
    while (stk) fout[top++] = st[stk--];
    return *this;
  }
  inline O& operator<<(char x) {
    fout[top++] = x;
    return *this;
  }
  inline O& operator<<(string s) {
    if (top > (1 << 20)) flush();
    for (char x : s) fout[top++] = x;
    return *this;
  }
} out;

#define pb emplace_back
#define fir first
#define sec second

template <class T>
inline void cmax(T& x, const T& y) {
  (x < y) && (x = y);
}
template <class T>
inline void cmin(T& x, const T& y) {
  (x > y) && (x = y);
}

const int qwq = 1e7;
int phi[qwq + 10];
int qpow(int x, int y, int p) {
  int ans = 1;
  for (; y; y >>= 1, x = 1ll * x * x % p)
    if (y & 1) ans = 1ll * ans * x % p;
  return ans;
}
int solve(int p) { return (p == 1) ? 0 : qpow(2, solve(phi[p]) + phi[p], p); }
signed main() {
#ifdef _WIN64
  freopen("testdata.in", "r", stdin);
#endif
  for (int i = 2; i <= qwq; i++) {
    if (phi[i]) continue;
    for (int j = i; j <= qwq; j += i) {
      if (!phi[j]) phi[j] = j;
      phi[j] = phi[j] / i * (i - 1);
    }
  }
  int T;
  in >> T;
  while (T--) {
    int p;
    in >> p;
    out << solve(p) << '\n';
  }
  return out.flush(), 0;
}

CF906D Power Tower

Given \ (a \ {\} \ ) lets you find \ (a_l ^ {a_ {l + 1} ^ {... ^ {a_r}}} \)

Then you will find that \ (\ varphi (x) \ ) when the log layer becomes 1, so recursion like violence, if they feel slow, you can give \ (\ varphi \) plus a memory of.

// by Isaunoya
#include <bits/stdc++.h>
using namespace std;

#define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
#define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
#define int long long

const int _ = 1 << 21;
struct I {
  char fin[_], *p1 = fin, *p2 = fin;
  inline char gc() {
    return (p1 == p2) && (p2 = (p1 = fin) + fread(fin, 1, _, stdin), p1 == p2) ? EOF : *p1++;
  }
  inline I& operator>>(int& x) {
    bool sign = 1;
    char c = 0;
    while (c < 48) ((c = gc()) == 45) && (sign = 0);
    x = (c & 15);
    while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
    x = sign ? x : -x;
    return *this;
  }
  inline I& operator>>(double& x) {
    bool sign = 1;
    char c = 0;
    while (c < 48) ((c = gc()) == 45) && (sign = 0);
    x = (c - 48);
    while ((c = gc()) > 47) x = x * 10 + (c - 48);
    if (c == '.') {
      double d = 1.0;
      while ((c = gc()) > 47) d = d * 0.1, x = x + (d * (c - 48));
    }
    x = sign ? x : -x;
    return *this;
  }
  inline I& operator>>(char& x) {
    do
      x = gc();
    while (isspace(x));
    return *this;
  }
  inline I& operator>>(string& s) {
    s = "";
    char c = gc();
    while (isspace(c)) c = gc();
    while (!isspace(c) && c != EOF) s += c, c = gc();
    return *this;
  }
} in;
struct O {
  char st[100], fout[_];
  signed stk = 0, top = 0;
  inline void flush() { fwrite(fout, 1, top, stdout), fflush(stdout), top = 0; }
  inline O& operator<<(int x) {
    if (top > (1 << 20)) flush();
    if (x < 0) fout[top++] = 45, x = -x;
    do
      st[++stk] = x % 10 ^ 48, x /= 10;
    while (x);
    while (stk) fout[top++] = st[stk--];
    return *this;
  }
  inline O& operator<<(char x) {
    fout[top++] = x;
    return *this;
  }
  inline O& operator<<(string s) {
    if (top > (1 << 20)) flush();
    for (char x : s) fout[top++] = x;
    return *this;
  }
} out;

#define pb emplace_back
#define fir first
#define sec second

template <class T>
inline void cmax(T& x, const T& y) {
  (x < y) && (x = y);
}
template <class T>
inline void cmin(T& x, const T& y) {
  (x > y) && (x = y);
}

int n, m, q;
vector<int> a;
map<int, int> phi;

int getphi(int x) {
  if (phi.count(x)) return phi[x];
  int res = x, qwq = x;
  for (int i = 2; i <= sqrt(x); ++i)
    if (!(x % i)) {
      res = res / i * (i - 1);
      while (!(x % i)) x /= i;
    }
  if (x > 1) res = res / x * (x - 1);
  return phi[qwq] = res;
}
int mod(int x, int p) { return (x < p) ? x : (x % p + p); }
int qpow(int x, int y, int p) {
  int ans = 1;
  for (; y; y >>= 1, x = mod(x * x, p))
    if (y & 1) ans = mod(ans * x, p);
  return ans;
}
int dfs(int l, int r, int p) {
  if (l == r || p == 1) return mod(a[l], p);
  return qpow(a[l], dfs(l + 1, r, getphi(p)), p);
}
signed main() {
#ifdef _WIN64
  freopen("testdata.in", "r", stdin);
#endif
  in >> n >> m;
  a.resize(n);
  for (int i = 0; i < n; i++) in >> a[i];
  in >> q;
  while (q--) {
    int l, r;
    in >> l >> r;
    --l, --r;
    out << dfs(l, r, m) % m << '\n';
  }
  return out.flush(), 0;
}

Guess you like

Origin www.cnblogs.com/Isaunoya/p/12457387.html