Description has only two Sentences

Description has only two Sentences

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


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

Author
WhereIsHeroFrom

Source

Recommend
wxl

题意:给出关系式an = X*an-1 + Y and Y mod (X-1) = 0.给出x,y, a0求最小的 ak mod a0 = 0.

解题: 题目描述很简单的说,然后我们可以推得这样一个公式: 
an = x^n * a0 + y*sigma(x+x^2+....+x^(n-1) )  --->  an = x^n*a0 + y/(x-1)*(x^n-1);
因为题目 给定  y mod (x-1) = 0 ;
那么 如果an % a0 == 0 ,则由(a + b) % p = (a % p + b % p) % p;
 那么 可以表示  (x^n*a0)%a0==0, ( y/(x-1)*(x^n-1) )%a0 == 0;
设 m = y/(x-1), g = gcd(a0,m),那么我们可以得到 ( x^n-1)%(a0/g) == 0;设c = a0/g;
转化为 x^n == 1(mod c );
那么我们可以得到  当 gcd( c,x ) != 1 时  无解
当gcd( c,x ) == 1 时,我们可以得到  x^eular(c) == 1 ( mod c);
但是这不一定是最小的,所以我们要枚举x的约数,求得最小的。



#include<iostream>
using namespace std;

typedef long long LL;

LL gcd(LL a,LL b) {
if( a < b) {
LL t = a;
a = b;
b = t;
}
if( b == 0) return a;
return gcd(b,a%b);
}

inline LL eular(LL n) {
LL i,ans = n,t = n;
for( i = 2 ; i * i <= n ;i++ )
if( t%i == 0) {
ans = ans/i*(i-1);
while( t%i == 0) t /= i;
}
if( t > 1) ans = ans/t*(t-1);
return ans; 
} 
const int N = 1000000;
LL dp[N];

LL erfen(LL a,LL k,LL mod)//a^k%mod
{
LL p=a%mod,t=1;
while(k)
{
if(k&1)t=(t*p)%mod;
p=(p*p)%mod;
k>>=1; 
} 
return t; 
}

int main() {
LL x,y,a,i;
while( cin>>x>>y>>a ) {
LL tmp = y/(x-1);
if( tmp == 0) {puts("1");continue;}
LL g = gcd(tmp,a);
a /= g;
if( gcd(a,x) != 1) puts("Impossible!");
else {
LL ans = eular(a);
LL size=0;
for(i=1;i*i<=ans;i++)
if(ans%i==0) {
dp[size++]=i;
if(ans/i!=i)dp[size++]=ans/i;
}
sort(dp,dp+size); 
for(i=0;i<size;i++)if(erfen(x,dp[i],a)==1)break;
cout<<dp[i]<<endl;
}
}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值