题意:输入n和a 定义m等于2的n次方 求1-m有多少数使得 a^b = b^a (mod m)
题解:先打表找规律 发现a为奇数的答案只有b = a这一种 (不知道为什么也不想知道为什么
当a为偶数时 因为m为偶数 所以 a ^ b % m肯定也为偶数 所以 b ^ a % m同理 b也为偶数
于是a可以写成2*k a^b可写作 2^b * k^b % (2^n) 显然b >= n时 肯定等于0嘛
然后分类讨论 b <= n时暴力搞搞
b > n时 就需要满足 b^a % (2^n)等于0了
同理就要满足b^a = 2^a * k^a % (2^n) = 0 那么假设k有x个2 使得(x + 1) * a >= n就好了
然后所有是这个最小的数倍数的数显然也满足 注意统计答案的时候还要减去暴力算<=n时的答案
总结:反正比赛中是肯定写不出来这个题的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #include <algorithm> #include <iostream> using namespace std; typedef long long ll; ll m; ll pow_mod(ll x, ll y) { ll res = 1; while(y) { if(y & 1) res = res * x % m; y >>= 1; x = x * x % m; } return res; } int main() { ll n, a; while(~scanf("%lld%lld", &n, &a)) { m = (1 << n); if(a & 1) { puts("1"); continue; } else { ll ans = 0; for(int i = 1; i <= n; i++) { ll o = pow_mod(a, i); ll u = pow_mod(i, a); if(o == u) ans++; } if(a > n) ans += m / 2 - n / 2; else { ll p; if(n % a != 0) p = n / a + 1; else p = n / a; p = (1LL << p); ans += m / p - n / p; } printf("%lld ", ans); } } return 0; }