现在的位置: 首页 > 综合 > 正文

hdu3307 Description has only two Sentences

2018年04月23日 ⁄ 综合 ⁄ 共 1067字 ⁄ 字号 评论关闭

刚开始花了很长时间化简,求出x^k mod a0=1来却不知道怎么去求解。。。。

看了解题报告,套用欧拉函数,因为 x^φ(a0) mod a0 =1,所以除了无解的情况,最大的解也不会超过φ(a0),然后比较φ(a0)的因子里,找一个最小的即可。

对于无解的情况,即 Gcd(x,a0)!=1 ,假设存在共同因子m,那么x=x' * m,a0=a0' * m;则 (x' * m)^k - t* (a0' * m) =1 ,化简 m*( x'^k * m^(k-1) - t*a0' )=1,显然,对于m大于1是无解的

code:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL __int64
using namespace std;
const int MAXN = 11;
int n;
LL Gcd(LL a, LL b)
{
    return b==0?a:Gcd(b,a%b);
}

LL PowMod(LL n,LL exp,LL mod)
{
    LL ret=1,tmp=n%mod;
    while(exp)
    {
        if(exp&1)
            ret=ret*tmp%mod;
        exp>>=1;
        tmp=tmp*tmp%mod;
    }
    return ret;
}

LL Eular(LL n)
{
    LL fac,ans=1;
    for(fac=2;fac*fac<=n;fac++)
    {
        if(n%fac==0)
        {
            n/=fac;
            ans*=fac-1;
            while(n%fac==0)
            {
                n/=fac;
                ans*=fac;
            }
        }
    }
    if(n>1) ans*=n-1;
    return ans;
}

LL solve(LL x,LL y,LL a0)
{
    if(y==0) return 1;
    LL gcd=Gcd(y/(x-1),a0);
    a0/=gcd;
    if(Gcd(a0,x)!=1) return -1;
    LL lim=Eular(a0);
    LL minn=lim;
    for(LL fac=2;fac*fac<=lim;fac++)
    {
        if(lim%fac==0)
        {
            if(PowMod(x,fac,a0)==1&&fac<minn)
                minn=fac;
            if(PowMod(x,lim/fac,a0)==1&&fac<minn)
                minn=lim/fac;
        }
    }
    return minn;
}

int main()
{
    LL x,y,a0,ans;
    while(~scanf("%I64d%I64d%I64d",&x,&y,&a0))
    {
        ans=solve(x,y,a0);
        if(ans==-1) puts("Impossible!");
        else printf("%I64d\n",ans);
    }
    return 0;
}

抱歉!评论已关闭.