Description has only two Sentences

来源:互联网 发布:淘宝买止咳水的暗语 编辑:程序博客网 时间:2024/05/29 10:38

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
HDOJ Monthly Contest – 2010.02.06

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;}}}