CF 334 div.2-D/div.1-B/603B Moodular Arithmetic


题目链接: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;
}


你可能感兴趣的:(CF 334 div.2-D/div.1-B/603B Moodular Arithmetic)