hdu 3307 欧拉定理+等比数列

利用等比数列知识,

an = x*an-1 + Y

故an +A = x * an-1 + Y + A

故an +A = x ( an-1 + (Y+A)/x)

令 A = (Y+A)/X

所以(X-1)*A = Y

得出 A = Y/(X-1)

所以{an+A}是等比数列;

所以an/a0 = X^n + P*(X^n-1)/a0

转换成X^n%(a0/p) = 1 符合欧拉定理,

所以由x^n组成的集合是个循环群,phi(a/p)是循环节,而且最小循环节必定是phi(a/p)的因数.

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;

typedef long long LL;

LL euler ( LL x )
{
    LL res = x;
    for ( LL i = 2 ; i * i <= x ; i++ )
    {
        if ( x%i==0 )
           res -= res/i;
        while ( x%i==0 ) x/=i; 
    }
    if ( x > 1 ) res -= res/x;
    return res;
}

LL gcd ( LL x , LL y )
{
    return y==0? x : gcd ( y , x%y );
}

LL pow2 ( LL num ,LL index , LL mod  )
{
    if ( index == 0 ) return 1;
    LL temp = pow2 ( num , index/2, mod  );
    if ( index &1 ) return temp%mod*temp%mod*num%mod;
    else return temp%mod*temp%mod;
}

int main ( )
{
    LL x , y , a;
    while ( ~scanf ( "%lld%lld%lld" , &x , &y , &a ) )
    {
        if ( y == 0 ) 
        {
            puts("1");
            continue;
        }
        LL p = y/(x-1);
        a = a/gcd ( p , a );
        if ( gcd ( x , a) == 1 )
        {
            LL n = euler ( a );
            LL minn = n;
            for ( LL i = 2 ; i*i <= n ; i++ )
            {
                if ( n%i ) continue;
                if ( pow2 ( x , i ,a ) == 1 )
                    minn = min ( i , minn );
                if ( pow2 ( x , n/i , a ) == 1 )
                   minn = min ( n/i , minn ); 
            }
            printf ( "%I64d\n" , minn );
        }
        else puts ( "Impossible!" );
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值