传送门:点击打开链接
题意:告诉你p和k,其中(0<=k<=p-1),x属于{0,1,2,3,....,p-1},f函数要满足f(k*x%p)=k*f(x)%p,f(x)的范围必须在[0.p-1]内,问这样的f函数有多少个
思路:首先这个怎么看都跟循环节有关。。那么怎么找到循环节呢。。
首先找k为0的情况,可以发现此时答案就是p^(p-1)
然后k为1的情况,答案就是p^p
如果k>=2
很明显可以发现f(0)=0是肯定的
假设k^r%p=1,r是最小满足这个条件的正整数
那么f(x),因为f(x)在[0,p-1]内,
所以f(x)=k^r*f(x)%p=k^(r-1)*f(k*x%p)=k^(r-2)*f((k^2)*x%p)=k^(r-3)*f((k^3)*x%p)=....
=k^(r-r)*f((k^r)*x%p)=f((k^r)%p*x%p)=f(x%p)=f(x)
可以发现,在上面这个式子中,这r个x组成了一个环,这个环的数字都是相等的
本来x的范围中有p个数字,除去x=0的情况,还有p-1个数字。
又因为k^(p-1)%p=1,k^r%p=1,所以r肯定是p-1的因数
所以,p-1是肯定能整除r的,那么剩下的p-1个数字就能分成(p-1)/r个环
对于每个环上的数字都应该相同,这个数字有p种情况,即[0,p-1],一共有(p-1)/r个环
所以答案是p^((p-1)/r)
#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;
const int MX = 100000 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int p, k;
int solve() {
int e;
if(k == 0) e = p - 1;
else if(k == 1) e = p;
else {
e = 1;
LL s = k;
while(s != 1) {
e++;
s = s * k % p;
}
e = (p - 1) / e;
}
LL ans = 1;
for(int i = 1; i <= e; i++) {
ans = ans * p % mod;
}
return ans;
}
int main() {
scanf("%d%d", &p, &k);
printf("%d\n", solve());
return 0;
}