题目链接:
题目大意:
给出f(kx mod p)≡kf(x) mod p,求满足条件的f(x)的数量。
题目分析:
首先考虑两种特殊情况,即k=0和k=1的情况。
- 当k = 0 时,
{f(x)=0f(x)={0,?p?1},x=0,x>0
因为k=0?f(kx mod p)≡f(0),x<p
所以只有f(0)必须等于0,其他的f(x)可以为任意值域中的值,所以方案数是pp?1
- 当k=1时,
f(x mod p)=f(x) mod p,x<p?x mod p=x,所以f(x),0≤x<p,f(x)可以为值域内任意值,所以方案数为pp
- 当k>1时,
- 我们令f(x) = n,那么会导致f(kx),f(k1x)?f(kmx)的值会被确定,而且会形成循环节,我们可以利用km≡1 mod p求得循环节的长度。
- 因为在0到m-1中kimod p的值不同,那么他们乘上一个常数n之后也一定是不同的。
- 然后我们可以通过p?1m知道这p-1个数一共存在多少个这种封闭的群,每个群只需要确定一个值,就确定了其他所有的值,所有说最后的方案数就是p?p?1m?
AC代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
int k,p;
const LL mod = 1e9+7;
LL pow1 ( LL x , LL n )
{
LL ret = 1;
LL num = x;
while ( n )
{
if ( n&1 )
{
ret *= num;
ret %= mod;
}
num *= num;
num %= mod;
n >>= 1;
}
return ret;
}
int main ( )
{
while ( ~scanf ( "%d%d" , &p , &k ) )
{
int m = 1;
LL temp = k;
if ( k == 0 )
{
printf ( "%lld\n" , pow1 ( p , p-1 ) );
continue;
}
if ( k == 1 )
{
printf ( "%lld\n" , pow1 ( p , p ) );
continue;
}
for ( ; m < p ; m++ )
{
if ( temp == 1 ) break;
temp *= k;
temp %= p;
}
int x = ceil((p-1)*1.0/m);
printf ( "%lld\n" , pow1 ( p , x ) );
}
}
时间: 2024-10-05 05:00:36