Codeforces Round #334 (Div. 2) D. Moodular Arithmetic 思维

来源:互联网 发布:华为路由器设置mac地址 编辑:程序博客网 时间:2024/06/05 10:31


题目链接:http://codeforces.com/contest/604/problem/D

题意:给定p ,k(p为奇质数)。一函数f(x)定义域和值域都为【0,p-1】,且满足f(k*i % p)==k*f(i)%p。问f(x)有多少种选择方式。

解法:

k==0时,只需满足f(0)==0,故ans=p^(p-1);

k==1时,f(x)==f(x),ans=p^p;

k>1时,有两种解法:

1.f(0)=0,对于其他的值,当f(x)确定时,f(k*x%p)也随之确定,f(k*k*x%p)也随之确定...相当于【1,p-1】被分为r个小环,确定每个环可以任选一个数字,ans=p^r。可以直接用dfs来实现。

2.(这种方法如何证明的不知道,留个坑)。r可以被(p-1)整除,即相当于找一个最小的len,使得(p-1)%len==0  &&  p^len%p==1,此时r=(p-1)/len。这种方法要快于上面的方法。

方法1的代码(31ms):

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <cmath>#include <vector>#include <set>#include <map>#include <stack>#include <queue>using namespace std;typedef long long LL;const int mod = 1e9 +7;LL fpow(LL x, int n){    LL ret = 1;    while (n){        if (n&1) ret = ret*x%mod;        x = x*x%mod;        n >>= 1;    }    return ret;}int mem[1000005];void dfs(int x){    if(x==-1)  return ;    int cur=mem[x];    mem[x]=-1;    dfs(cur);}int main (){    int p,k;    while(scanf("%d%d",&p,&k)!=EOF){        if(k<=1){            if(k==0)    printf("%d\n",fpow(p,p-1));            else        printf("%d\n",fpow(p,p));            continue ;        }        for(int i=0;i<p;i++)            mem[(LL)k*i%p]=i;        int cnt=0;        for(int i=1;i<p;i++)        if(mem[i]!=-1){            cnt++;            dfs(i);        }        printf("%d\n",fpow(p,cnt));    }    return 0;}

方法2(15ms):

#include <stdio.h>#include <stdlib.h>#define MOD 1e9 + 7long long power(long long a, long long b, long long m) {long long c = 1;for(; b; b >>= 1) {if(b & 1) {c = (c * a) % m;}a = (a * a) % m;}return c;}long long solve(long long p, long long k) {long long ord, i;switch(k) {case 0:return power(p, p-1, MOD);case 1:return power(p, p, MOD);}ord = p - 1;for(i = 2; i < ord; i++) {if(ord % i == 0) {if(power(k, ord / i, p) == 1) {ord = ord / i;i--;}}}return power(p, (p - 1) / ord, MOD);}int main() {long long p, k;scanf("%I64d%I64d", &p, &k);printf("%I64d\n", solve(p, k));return 0;}


0 0
原创粉丝点击