CF 603B 数学,同余

来源:互联网 发布:可以标记的地图软件 编辑:程序博客网 时间:2024/05/29 19:39

题目大意:给出方程f(kx%p)=kf(x)%p ,问在集合A->B上不同的映射函数f 有几种,其中A=B={0,1,2..p-1},p为素数(除了2),k为小于p的一个常数


思路: 因为f(kx%p) , 将x = kx 带入得f(kx%p) = f(k*kx%p),所以乘以k除以k相等,所以f(x%p) = f(kx%p) , 又因为f(kx%p)=kf(x)%p  , 所以f(x%p)  = k*k*k*k……%p,肯定存在循环节,找到循环节m。起始项有p个,每个都有p/m个环即不同的组成方式。所以结果为p^(p/m), 特判k=0和k=1的情况即可。


#include <cstdio>#include <string>#include <cstring>#include <fstream>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <iomanip>#include <iostream>using namespace std;#define maxn 1000003#define MOD 1000000007#define mem(a , b) memset(a , b , sizeof(a))#define LL __int64int p , k;LL powe(LL n , LL m ){    LL ans = 1;    while(m > 0)    {        if(m&1) ans = (ans * n) % MOD;        m >>= 1;        n = (n * n) % MOD;    }    return ans;}int main(){    while(scanf("%d %d" , &p , &k) != EOF)    {        LL m = 1 , x = 1;        for(int i = 1 ; i <= p ; i ++)        {            x = x*k % p;            if(x == 1)break;            m++;        }      //  cout << m << endl;        LL ans = 0;        if(k == 0) ans = powe(p , p-1);        else if(k == 1) ans = powe(p , p);        else ans = powe(p , (p) / m);        printf("%I64d\n" ,ans);    }    return 0;}


0 0