0
点赞
收藏
分享

微信扫一扫

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


题目链接:

codeforce 603B

题目大意:

给出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 ) );     
    }
}


举报

相关推荐

0 条评论