hdu3307 欧拉函数

Posted chen99

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu3307 欧拉函数相关的知识,希望对你有一定的参考价值。

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3307

Description has only two Sentences

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1733    Accepted Submission(s): 525


Problem Description
an = X*an-1 + Y and Y mod (X-1) = 0.
Your task is to calculate the smallest positive integer k that ak 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
 

 

 an = X*an-1 + Y ,给你X,Y,a0,叫你求出最小的整数k(k>0)使得 ak% a0=0。根据公式我们可以求出an= a0*Xn-1+(x0+x1+x2+……+xn-1)Y。由等比数列前项和公式可得

 an=a0*Xn-1+(xn-1)*Y/(x-1)。

所以只需令(xk-1)*Y/(x-1)%a0=0,求出k的值。

令Y‘=Y/(x-1),d=gcd(Y/(x-1),a0)

Y‘/=d,a0/=d;

此时Y‘与a0互质

(xk-1)*Y/(x-1)%a0=0

等价于

(xk-1)%a0=0

xk%a0=1

而这就符合欧拉定理aφ(n)Ξ 1(mod n)

如果gcd(x,a0)!=1则k无解

否则求出phi(a0)再除以满足条件的phi(a0)的因子

#include<iostream>
using namespace std;
#define ll long long
ll zys[1000][2],cnt;
ll gcd(ll a,ll b)
{
    return b?gcd(b,a%b):a;
}
ll phi(ll x)
{
    ll ans=x;
    for(ll i=2;i*i<=x;i++)
    {
        if(x%i==0)
        {
            ans=ans/i*(i-1);
            while(x%i==0)x/=i;
        }
    }
    if(x>1)
    ans=ans/x*(x-1);
    return ans;
}
void fj(ll ans)
{
    for(ll i=2;i*i<=ans;i++)
    {
        if(ans%i==0)
        {
            zys[cnt][0]=i;
            zys[cnt][1]=0;
            while(ans%i==0)
            {
                ans/=i;
                zys[cnt][1]++;
            }
            cnt++;
        }
    }
    if(ans>1)
    {
        zys[cnt][0]=ans;
        zys[cnt++][1]=1;
    }
}
ll poww(ll a,ll b,ll mod)
{
    ll ans=1;
    while(b)
    {
        if(b&1)ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
int main()
{
    ll x,y,a,c,d;
    while(cin>>x>>y>>a)
    {
        if(x==1)
        {
            if(gcd(y,a)==1)cout<<a<<endl;
            else cout<<a/gcd(y,a);
            continue;
        }
        c=y/(x-1);
        if(c%a==0)
        {
            cout<<1<<endl;
            continue;
        }
        d=gcd(c,a);
        if(gcd(x,a/d)!=1)cout<<"Impossible!"<<endl;
        else
        {
            a/=d;
            ll ans=phi(a);
            cnt=0;
            fj(ans);
            for(int i=0;i<cnt;i++)
            {
                for(int j=1;j<=zys[i][1];j++)
                {
                    if(poww(x,ans/zys[i][0],a)==1)ans/=zys[i][0];
                }
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}

 

以上是关于hdu3307 欧拉函数的主要内容,如果未能解决你的问题,请参考以下文章

hdu 6390 欧拉函数+容斥(莫比乌斯函数) GuGuFishtion

HDU 1286 找新朋友 (欧拉phi函数打表)

hdu 2824(欧拉函数)

POJ 2478 欧拉函数(欧拉筛法) HDU 1576 逆元求法

HDU1695-GCD(数论-欧拉函数-容斥)

hdu-1286 找新朋友(欧拉函数,水题)