Description has only two Sentences
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 886 Accepted Submission(s): 265
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.
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
题目要求求一个 Ai = XAi + Y and Y %(x-1) == 0 的 Ak % A0 == 0 的最小 k
然后开始推公式
可得 A n = X^n * A0 + ( x^(n-1) + x *(n-2) + ...... + x + 1 ) * Y
显然 X^n * A0 必然整除 A0 可以忽略 , 然后 后项是一个等比数列 。
然后处理一下得到想要求的就是 ( X ^ k -1 )/ ( x - 1 ) * Y % A0 == 0 的最小k
转换一下 。。 设系数为 e ,
就是 e * A0 = ( X^k - 1 ) / (X - 1 ) * Y ;
e * ( A0 / gcd(A0 , Y / (X - 1 ) ) ) = X^k - 1 。
设 m = ( A0 / gcd(A0 , Y / (X - 1 ) ) ) .
得到 X^k == 1 ( mod m )
对m求一次单个欧拉 , 然后判一下 。
impossible 那里要特判一下X与m是否互质 ,若不互质,则X^k%m必定是gcd(m,X)的倍数
#include <algorithm> #include <cstring> #include <cstdio> #include <queue> #include <iostream> #include <vector> #include <string> #include <map> using namespace std; typedef long long ll; const int N = 100010; ll mod , tot ; ll gcd ( ll a , ll b ) { return b == 0 ? a : gcd( b ,a % b ); } ll eular ( ll n ) { ll sum = n ; for( ll i = 2 ; i* i <= n ; ++i ){ if( n % i == 0 ){ sum = sum / i *( i -1 ); while( n % i == 0 ) n /= i ; } } if( n > 1 ) sum = sum / n * ( n -1 ) ; return sum; } ll quick_mod( ll a , ll b ) { ll res = 1 ; while( b ){ if( b & 1 ) res = res * a % mod ; a = a * a % mod; b >>= 1 ; } return res ; } ll e[N] ; void get_factor( ll n ) { for( ll i = 2 ; i * i <= n ; ++i ){ if( n % i == 0 ){ e[tot++] = i ; if( n / i != i ) e[tot++ ] = n / i ; } } } int main() { ios::sync_with_stdio(0); #ifdef LOCAL freopen("in.txt","r",stdin); #endif ll a0 , x , y ; while( cin >> x >> y >> a0 ){ tot = 0 ; if( !y ) { cout << '1' <<endl ; continue ;} ll m = a0 / gcd( y / ( x - 1 ) ,a0 ) ; if( gcd(m ,x) != 1 ) { cout << "Impossible!" << endl ; continue ; } ll phi = eular(m) ; get_factor(phi) ; sort(e , e + tot ) ; mod = m ; for( int i = 0 ; i < tot ; ++i ){ if( quick_mod( x,e[i]) == 1 ){ cout <<e[i] << endl ; break ; } } } }