hdu 4335(数论)
降幂公式
A ^ x = A ^ (x % Phi(C) + Phi(C) ) (mod C) (x>=Phi(C))
typedef unsigned long long ull;
const double eps = 1e-6;
ull get_eular(ull m) {
ull ret = 1;
for (ull i = 2; i * i <= m; ++i) {
if (m % i == 0) {
ret *= i - 1;
m /= i;
while (m % i == 0) {
m /= i;
ret *= i;
}
}
}
if (m > 1)
ret *= m - 1;
return ret;
}
ull qmod(ull a, ull b, ull mod) {
ull ret = 1;
while (b) {
if (b & 1)
ret = (ret * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return ret;
}
ull b, p, m, ring[100005];
int main() {
int t, cas = 0;
scanf("%d", &t);
while (t--) {
scanf("%I64u%I64u%I64u", &b, &p, &m);
printf("Case #%d: ", ++cas);
if (p == 1) {
if (m == 18446744073709551615ULL)
printf("18446744073709551616\n");
else printf("%I64u\n", m + 1);
continue;
}
ull i = 0, phi = get_eular(p), fac = 1, ans = 0;
//第一个环节, n! < phi(p)
for (i = 0; i <= m && fac <= phi; ++i) {
if (qmod(i, fac, p) == b)
ans++;
fac *= i + 1;
}
fac = fac % phi;
//第二个环节, n ^ (n! % phi(p) + phi(i) )直到指数固定为phi(p)
for (; i <= m && fac; ++i) {
if (qmod(i, fac + phi, p) == b)
ans++;
fac = (fac * (i + 1) % phi);
}
if (i <= m) {
ull cnt = 0;
// 打表一个循环
for (int j = 0; j < p; ++j) {
ring[j] = qmod(i + j, phi, p);
if (ring[j] == b)
cnt++;
}
ull idx = (m - i + 1) / p;
ans += cnt * idx;
ull remain = (m - i + 1) % p;
for (int j = 0; j < remain; ++j)
if (ring[j] == b)
ans++;
}
printf("%I64u\n", ans);
}
return 0;
}