当 a 为偶数时: 因为a为偶数, 则a可以表示为 a = 2*k a^b%mod 可表示为: a^b%mod = 2^b * k^ b % 2 ^ n 当b >= n 时, a^b%mod == 0 恒成立 所以就要求满足此式: a^b%mod == b^a%mod == 0 此时b肯定为偶数 则 b = 2*x 要求成立: b^a%mod = 2^a * x^a % 2^n == 0 所以分为两种情况: 1. a > n 时: b^a%mod = 2^a * x^a % 2^n == 0 恒成立 结果为[1, mod]中的所有数-奇数情况-暴力情况 2. a <= n 时: x一定要是一个2次幂数即 x = 2^p, (p*a) >= n 成立, 找到所有满足 p >= n/a 的数, 所以找到所有的数t, 满足 t >= x(x = 2^p) && t <= mod(mod = 2^n), 满足条件的数的数量为 mod/x - n/x 当b < n 时, 暴力求解
#include <cmath>#include <cstdio>#include <iostream>usingnamespacestd;
typedeflonglong ll;
ll mod;
ll qpow(ll a, ll b) {
ll res = 1;
while (b) {
if (b & 1)
res = res * a % mod;
b >>= 1;
a = a * a % mod;
}
return res;
}
int main() {
ll n, a;
while (~scanf("%lld%lld", &n, &a)) {
// a % 2 == 1; 结果恒为1
mod = (1LL << n);
if (a % 2 == 1) {
printf("1\n");
continue;
} else {
// b < n; 暴力求解
ll res = 0;
for (ll b = 1; b <= n; ++b) {
ll t1 = qpow(a, b);
ll t2 = qpow(b, a);
if (t1 == t2) {
res++;
}
}
if (a > n) {
res += mod / 2 - n / 2;
} else {
ll x;
if (n % a != 0)
x = n / a + 1;
else
x = n / a;
x = (1LL << x);
res += mod / x - n / x;
}
printf("%lld\n", res);
}
}
return0;
}