码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-12-02 12:37:01      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

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),0x<pf(x)pp
  • 当k>1时,
    • 我们令f(x) = n,那么会导致f(kx),f(k1x)?f(kmx)的值会被确定,而且会形成循环节,我们可以利用km1 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 ) );     
    }
}

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

标签:

原文地址:http://blog.csdn.net/qq_24451605/article/details/50145513

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!