题意:求满足以下条件的n有多少个:
方法居然是枚举。。。
用到一个降幂公式:
当n大于p的欧拉函数的值的时候,显然n!%phi(p) == 0,即只需要求:n ^(phi(p)),所以以后的值是循环的:
#include <iostream>
#include <cmath>
#include <cstdio>
#define lng unsigned long long
using namespace std;
lng get_phi(lng n)
{
lng ans = n;
lng m = (lng)sqrt(n + 0.5);
for(lng i = 2; i <= m; ++i)
{
if(n % i == 0)
{
ans *= (i - 1);
ans /= i;
while(n % i == 0) n /= i;
}
}
if(n > 1) {
ans *= (n - 1);
ans /= n;
}
return ans;
}
lng pow_mod(lng a, lng b, lng n)
{
if(b == 0) return 1;
lng ans = pow_mod(a, b / 2, n);
ans = (ans * ans) % n;
if(b & 1) ans = (ans * a) % n;
return ans;
}
lng p, m, b, n;
lng num[100000 + 10];
int main()
{
int t;
cin >> t;
int cc = 1;
while(t--)
{
cin >> b >> p >> m;
printf("Case #%d: ", cc++);
if(p == 1 && b == 0)
{
if(m == 18446744073709551615ULL) cout << "18446744073709551616\n";
else cout << m + 1 << "\n";
continue;
}
lng ans = 0;
lng phi = get_phi(p), fac = 1;
for(n = 0; fac < phi && n <= m; ++n)
{
if(pow_mod(n, fac, p) == b) ans++;
fac *= n + 1;
}
for(; n < phi && n <= m; ++n)
{
if(pow_mod(n, fac + phi, p) == b) ans++;
fac *= n + 1;
fac %= phi;
}
if(n <= m)
{
lng tmp = 0;
for(int i = 0; i < p && n <= m; ++i, ++n)
{
num[i] = pow_mod(n, phi, p);
if(num[i] == b) ans++, tmp++;
}
if(n <= m)
{
lng d = m - n + 1;
ans += ((d / p) * tmp);
n = m - (d % p) + 1;
for(int i = 0; n <= m; ++i, ++n)
if(num[i] == b) ans++;
}
}
cout << ans << "\n";
}
return 0;
}