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,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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值