codeforces #334 div1 B 603B Moodular Arithmetic(数论)

来源:互联网 发布:曼秀雷敦护手霜 知乎 编辑:程序博客网 时间:2024/06/06 02:14

题目链接:

codeforce 603B


题目大意:

给出f(kx mod p)kf(x) mod p,求满足条件的f(x)的数量。


题目分析:

首先考虑两种特殊情况,即k=0和k=1的情况。

  • 当k = 0 时,
    {f(x)=0f(x)={0,p1},x=0,x>0

    因为k=0f(kx mod p)f(0),x<p
    所以只有f(0)必须等于0,其他的f(x)可以为任意值域中的值,所以方案数是pp1
  • 当k=1时,
    f(x mod p)=f(x) mod p,x<px mod p=x,f(x),0x<pf(x)pp
  • 当k>1时,
    • 我们令f(x) = n,那么会导致f(kx),f(k1x)f(kmx)的值会被确定,而且会形成循环节,我们可以利用km1 mod p求得循环节的长度。
    • 因为在0到m-1中kimod p的值不同,那么他们乘上一个常数n之后也一定是不同的。
    • 然后我们可以通过p1m知道这p-1个数一共存在多少个这种封闭的群,每个群只需要确定一个值,就确定了其他所有的值,所有说最后的方案数就是pp1m

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 ) );         }}
0 0
原创粉丝点击