题目链接:http://codeforces.com/problemset/problem/603/B
已知:f(k*x mod p)==k*f(x) mod p,对于一个从f:{0,1,2...p-1}→{0,1,2...p-1}的映射,问对于给定的p和k,有多少种满足已知等式的映射,答案对10^9+7取模。
已知:f(k*x mod p)==k*f(x) mod p,而且(a*b)%m=(a%m8b%m)%m。可以推出:f(k^2 *x mod p)==k^2 *f(x) mod p
进而可以推出,f(k^i *x mod p)==k^i *f(x) mod p。
当k=0时,有f(0)=f(0),所以答案是p^(p-1) %(10^9+7)。
当k=1时,有f(x)=f(x),所以答案是p^p %(10^9+7)。
当k=0时,显然ans=p^p-1;k=1时,ans=p^p。
k>=2时,由费马小定理得,k^p-1 ==1 mod p,所以必存在m(0<m<p),使得k^m ==1 mod p,,
所以对k^1 mod p,k^2 mod p...k^m mod p各自对应m个不同的数,而后k^i mod p对任意0<i<p,必对应这m个数里的某一个,所以如果我们确定了f(n),则f(k^1 * n mod p),f(k^2 * n mod p)...f(k^(m-1) * n mod p)也随之确定。所以,如果我们使f(n)对应(p-1)/m个数,那么我们就能得到所有p-1个非0的数,所以答案应该是p^[(p-1)/m]%(10^9+7)。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; #define mod 1000000007 long long fastpow(long long a, long long b,long long c) { long long temp = a, res = 1; while (b) { if (b & 1) res = res*temp%c; temp = temp*temp%c; b >>= 1; } return res; } int main() { //freopen("input.txt", "r", stdin); long long p, k, ans; scanf("%I64d%I64d", &p, &k); if (k == 0) ans = fastpow(p, p - 1, mod); else if (k == 1) ans = fastpow(p, p, mod); else { long long m = 1, x = k; while (x != 1) { x = x*k%p; ++m; } ans = fastpow(p, (p - 1) / m, mod); } printf("%I64d\n", ans); //system("pause"); //while (1); return 0; }