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
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 1001000
using 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;
}
哈哈