题意 给定 b,p,m 求 满足 n^(n!) %p =b ( 0<=n<=m) n 的个数
m 的范围 2^64 -1 这里是个trick。。。
利用降幂的公式 。 a^x %p= a^( x%phi(p) + phi(p)) %p
就可以把指数降到 1 - p 这个范围内。
对于 kp+1 ~ (k+1)p (k>1)这个范围中的n 可以 映射到 1 - p 这个范围。且指数必定是phi(p) 因为 x = a! ,a>phi(p) ---> x%phi(p) = 0;
然后对 区间暴力。。
坑爹的地方是 m = 2^64-1 p = 1 b =0 时 ,ans = 2^64 溢出 特判。。。。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <cstring>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <assert.h>
#include <queue>
#define REP(i,n) for(int i=0;i<n;i++)
#define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)
#define ALLL(x) x.begin(),x.end()
#define SORT(x) sort(ALLL(x))
#define CLEAR(x) memset(x,0,sizeof(x))
#define FILLL(x,c) memset(x,c,sizeof(x))
using namespace std;
const double EPS = 1e-8;
#define LL unsigned long long
#define pb push_back
const int maxn = 100001;
int p, b;
LL m;
LL phi(LL a){
LL ans = 1;
for(LL i=2;i*i<=a;i++){
if(a%i==0){
ans *= i-1;
a/=i;
while(a%i==0){
ans *= i;
a/= i;
}
}
}
if(a > 1){
ans*=a -1;
}
return ans;
}
LL fac[maxn];
LL pow(LL a,LL b,LL p){
LL ret = 1;
while(b){
if(b&1){
ret *= a;
ret %= p;
}
a = a*a;
a%= p;
b= b>>1;
}
return ret;
}
void solve(){
LL ret = 0;
LL f= phi(p);
fac[0] =1;
for(LL i=1;i<=p;i++){
fac[i] = fac[i-1]*i;
fac[i]%= f;
}
for(LL i=1;i<=p;i++){
if(i>m){
if(0==b)ret ++ ;
printf("%d\n",(int)ret);
return;
}
if(pow(i,fac[i]+f,p)==b){
ret ++;
}
}
LL d = (m- p)/p;
LL k = ( m - p)%p;
LL ans = 0;
for(LL i=1;i<=p;i++){
if(pow(i,f,p) == b){
if(i<=k){
ret ++;
}
ans ++;
}
}
ret += ans*d;
if(0==b)ret ++ ;
cout << ret << endl;
}
int main(){
int t;
cin >>t ;
for(int i= 1;i<=t;i++){
cin>>b>> p;
cin >> m;
// cout << m << " "<< p << " "<< b << endl;
if(m == 18446744073709551615llu && p == 1 && b == 0) {
printf("Case #%d: 18446744073709551616\n", i);
}else{
printf("Case #%d: ",i);
solve();
}
}
return 0;
}