Description has only two Sentences HDU

来源:互联网 发布:mysql认证考试报名 编辑:程序博客网 时间:2024/05/15 13:46

Description has only two Sentences HDU - 3307
题目:
a n = X*a n-1 + Y and Y mod (X-1) = 0.
Your task is to calculate the smallest positive integer k that a k mod a0 = 0.
Input
Each line will contain only three integers X, Y, a0 ( 1 < X < 231, 0 <= Y < 263, 0 < a0 < 231).
Output
For each case, output the answer in one line, if there is no such k, output "Impossible!".
Sample Input
2 0 9
Sample Output
        1

   就是求最小的k使a(k)满足ak mod a0 = 0.
   开始就是推公式 :
    an=a(0)*x^a(0)+(1+x+x^2+...+x^(n-1)*y;
    an%a(0)==0   ——》an%a(0)=(1+...+x^(n-1))*y%a(0)
                                                    =(x^n-1)/(x-1)*y%a(0);
          令    Y=y/(x-1) 
          原式= (x^n-1)*Y%mod==0;
          令    p=gcd(Y,mod)
                       mod=mod/p;Y=Y/p;
                                       (x^n-1)%mod==0;
                                                                      x^n%mod=1%mod;
          好吧确实不怎么好看。
          建议手动推一下。最后得到一个重要的式子:
     
                       (X^n)%mod=1%mod;
          首先对于gcd(x,mod)!=1时,无解。因为 :(X^n)%mod=0;
          然后就是一个欧拉定理了。


  





            就是这个了。
            
            那么怎么去找最小的k咧。
            首先算出    phi(mod)       (欧拉值)
            然后枚举每个因子。
         
          代码



#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define maxn 1001000using namespace std;typedef long long ll;ll d[maxn];int Pow(ll a,ll b,ll mod){    ll ans=1;    a=a%mod;    while(b)    {        if(b&1)            ans=ans*a%mod;        a=a*a%mod;        b>>=1;    }    return (ans%mod+mod)%mod;}ll phi(ll n){    ll rea = n;    for(ll i=2; i*i<=n; i++)    {        if(n % i == 0)        {            rea = rea - rea / i;            while(n % i == 0) n /= i;        }    }    if(n > 1)        rea = rea - rea / n;    return rea;}ll gcd(ll a,ll b){    if(b==0)        return a;    else        return gcd(b,a%b);}int main(){    ll x,y,a;    while(scanf("%lld%lld%lld",&x,&y,&a)!=EOF)    {        if(y==0)        {            puts("1");            continue;        }        ll y1=y/(x-1);        ll y2=gcd(y1,a);        ll mod=a/y2;        if(gcd(mod,x)!=1)        {            puts("Impossible!");            continue;        }        else        {            ll ph=phi(mod);            ll cnt=0;            for(ll i=1;i*i<=ph;i++)            {                if(ph%i==0)                {                    d[cnt++]=i;                    if(ph/i!=i)                        d[cnt++]=ph/i;                }            }            sort(d,d+cnt);            for(ll i=0;i<cnt;i++)            {                if(Pow(x,d[i],mod)==1)                {                    cout<<d[i]<<endl;                    break;                }            }        }    }    return 0;}










哈哈

                                   
                                                                                   
原创粉丝点击