hdu3307 Description has only two Sentences(欧拉函数)

题意:
给你三个数 X , Y , a 0 X,Y,a_0 ,且 a n = X a n 1 + Y a n d   Y m o d   ( X 1 ) = 0. a_n = X*a_n-1 + Y and \ Y mod \ (X-1) = 0.
让你求一个最小的 k k ,使得 a k m o d      a 0 = 0 a_k\mod\ a_0 = 0 ,若不存在输出Impossible!。
思路:
首先我们要找到 a k a_k a 0 a_0 的关系。
有以上递推式可得
a 1 = X a 0 + Y a_1=X*a_0+Y

a 2 = X a 1 + Y = X 2 a 0 + Y + X Y a_2=X*a_1+Y=X^2*a_0+Y+X*Y

a 3 = X a 2 + Y = X 3 a 0 + Y + X Y + X 2 Y a_3=X*a_2+Y=X^3*a_0+Y+X*Y+X^2*Y
. . . . . .....
a k = X k a 0 + Y + X Y + X 2 Y + . . . . + X k 1 Y a_k=X^k*a_0+Y+X*Y+X^2*Y+....+X^{k-1}*Y

      = X k a 0 + Y X k 1 X 1 \ \ \ \ \ =X^k*a_0+Y*\dfrac{X^k-1}{X-1}

根据题意有
a 0     a k a_0\ |\ a_k


a 0     Y X k 1 X 1 a_0\ |\ Y*\dfrac{X^k-1}{X-1}


( X 1 ) a 0     Y ( X k 1 ) (X-1)*a_0 \ |\ Y*(X^k-1)

d = g c d ( ( X 1 ) a 0 , Y ) d=gcd((X-1)*a_0,Y)

那么有

( X 1 ) a 0 d     Y d ( X k 1 ) \dfrac{(X-1)*a_0}{d} \ |\ \dfrac{Y}{d}*(X^k-1)

( X 1 ) a 0 d \dfrac{(X-1)*a_0}{d} Y d \dfrac{Y}{d} 互质

所以有

( X 1 ) a 0 d     ( X k 1 ) \dfrac{(X-1)*a_0}{d} \ |\ (X^k-1)

p = ( X 1 ) a 0 d p=\dfrac{(X-1)*a_0}{d}

p     ( X k 1 ) p\ |\ (X^k-1)

X k 1 ( m o d    p ) X^k\equiv 1(\mod p)

显然上述模线性方程有整数解当且仅当 g c d ( X , p ) = 1 gcd(X,p)=1
接下来 寻找最小的 k k
有一个结论是:
若存在 k k 满足上述模线性方程,那么有 k     φ ( p ) k\ | \ φ(p) ,即 k k φ ( p ) φ(p) 的因子,所以我们只需要在 φ ( p ) φ(p) 的因子里验证一下是否存在最小的 k k 即可。
注意当 Y = 0 Y=0 时,

a 0     Y X k 1 X 1 a_0\ |\ Y*\dfrac{X^k-1}{X-1} 显然成立,特判一下

上面推导过程是一般的流程,我因为忘了有 ( X 1 )     Y (X-1)\ |\ Y 这个条件,所以可能较麻烦,各位看官可以自己加上这个条件自己推一下,似乎就不用特判 Y = 0 Y=0 时了。

A C   C o d e : AC \ Code:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 2e6; 
ll phi(ll n){
    ll ans = n;
    for(ll i = 2;i <= sqrt(n);++i){
        if(n % i == 0){
            ans = ans / i * (i - 1);
            while(n % i == 0) n /= i;
        }
    }
    if(n > 1) ans = ans /n *(n - 1);
    return ans;
}
ll Qpow(ll a,ll b,ll p){
    ll ans = 1;
   // a %= p;
    while(b){
        if(b&1) ans = ans * a % p;
        b >>= 1;
        a = a * a % p;
    }
    return ans;
}
int main(){
    ll x,y,a0;
    while(cin>>x>>y>>a0){
        if(y == 0) {
            puts("1");
            continue;
        }
        ll d = __gcd((x-1)*a0,y);
        ll k = (x-1)*a0/d;
        if(__gcd(x,k) != 1) puts("Impossible!");
        else {
            ll a = phi(k);
            ll ans = (ll)1e16;
            if(Qpow(x,a,k) == 1) ans = a;
            for(ll i = 1;i <= sqrt(a);++i){
                if(a % i == 0){
                    if(Qpow(x,i,k) == 1) ans = min(ans,i);
                    if(Qpow(x,a/i,k) == 1) ans = min(ans,a/i);
                }
            }
            if(ans == (ll)1e16) puts("Impossible!");
            else cout<<ans<<endl;
        }
    }
}
发布了632 篇原创文章 · 获赞 27 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_43408238/article/details/104000144