hdu-3307 (欧拉定理+推导)
2017-08-20 18:44
260 查看
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.
InputEach line will contain only three integers X, Y, a0 ( 1 < X < 231, 0 <= Y < 263, 0 < a0 < 231).OutputFor each case, output the answer in one line, if there is no such k, output "Impossible!".Sample Input2 0 9Sample Output1
题目题意:题目给你三个数x,y,a0 ,我们知道了一个等式,an=x*an-1+y 并且y mod x-1 ==0 让我们求一个最小的k使得ak % a0 =0.题目分析:我们首先对那个等式变一下形,高中数列基础比较好的话,对这样的式子比较敏感的。比较简单,为了方便,下面简单写了一下:
得到了这个式子,我们的题目是要让它为0,我们取B与a0的最大公约数gcd(B,a0),那么我们可以得到(x^n-1)*b%a0等价为(x^n-1)*(b%gcd)%(a0%gcd)因为(b%gcd)%(a0%gcd)肯定不会为0了,它们的最大公约数都没又来,不能在约了,所以要使得等式为0,只有使得(x^n-1)%(a0%gcd)==0,我们变一下形:x^n-1=k*(a0%gcd) x^n=k*(a0%gcd)+1左右模a0%gcd即 x^n=1%(a0%gcd)这个式子已经满足欧拉定理形式了。在数论中,欧拉定理,(也称费马-欧拉定理)是一个关于同余的性质。欧拉定理表明,若n,a为正整数,且n,a互质,则:
题目要找是最小的,那么就是phi
的因子。代码如下:
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.
InputEach line will contain only three integers X, Y, a0 ( 1 < X < 231, 0 <= Y < 263, 0 < a0 < 231).OutputFor each case, output the answer in one line, if there is no such k, output "Impossible!".Sample Input2 0 9Sample Output1
题目题意:题目给你三个数x,y,a0 ,我们知道了一个等式,an=x*an-1+y 并且y mod x-1 ==0 让我们求一个最小的k使得ak % a0 =0.题目分析:我们首先对那个等式变一下形,高中数列基础比较好的话,对这样的式子比较敏感的。比较简单,为了方便,下面简单写了一下:
得到了这个式子,我们的题目是要让它为0,我们取B与a0的最大公约数gcd(B,a0),那么我们可以得到(x^n-1)*b%a0等价为(x^n-1)*(b%gcd)%(a0%gcd)因为(b%gcd)%(a0%gcd)肯定不会为0了,它们的最大公约数都没又来,不能在约了,所以要使得等式为0,只有使得(x^n-1)%(a0%gcd)==0,我们变一下形:x^n-1=k*(a0%gcd) x^n=k*(a0%gcd)+1左右模a0%gcd即 x^n=1%(a0%gcd)这个式子已经满足欧拉定理形式了。在数论中,欧拉定理,(也称费马-欧拉定理)是一个关于同余的性质。欧拉定理表明,若n,a为正整数,且n,a互质,则:
题目要找是最小的,那么就是phi
的因子。代码如下:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #define ll long long using namespace std; const int maxn=1e6+10; int prime[maxn],cnt; bool vis[maxn]; void get_prime()//素数打表 { memset (vis,true,sizeof (vis)); vis[1]=false; for (int i=2;i<maxn;i++) { if (vis[i]) prime[cnt++]=i; for (int j=i;j<cnt&&i*prime[j]<maxn;j++) { vis[i*prime[j]]=false; if (i%prime[j]==0) break; } } } ll gcd (ll a,ll b) { if (b==0) return a; return gcd(b,a%b); } ll factor[100][2],fcnt; void get_factor(ll n)//质因子分解 { memset (factor,0,sizeof (factor)); fcnt=0; for (int i=0;i<cnt&&prime[i]*prime[i]<=n;i++) { if (n%prime[i]==0) { factor[fcnt][0]=prime[i]; while (n%prime[i]==0) { factor[fcnt][1]++; n=n/prime[i]; } fcnt++; } } if (n!=1) { factor[fcnt][0]=n; factor[fcnt++][1]=1; } } ll fast_pow(ll base,ll k,ll mod)//快速幂 { ll ans=1; while (k) { if (k&1) ans=ans*base%mod; base=base*base%mod; k>>=1; } return ans; } ll get_euler(ll n) { ll res=n,a=n; for (ll i=2;i*i<=n;i++) { if (a%i==0) { res=res/i*(i-1); while (a%i==0) a=a/i; } } if (a>1) res=res/a*(a-1); return res; } int main() { get_prime(); ll x,y,a; while (scanf("%lld%lld%lld",&x,&y,&a)!=EOF) { y=y/(x-1); ll gc=gcd (y,a); a=a/gc; if (gcd (a,x)!=1) {//不满足欧拉定理 printf("Impossible!\n"); continue; } ll phi=get_euler(a),ans; get_factor(phi); ans=phi; for (int i=0;i<fcnt;i++) { for (int j=0;j<factor[i][1];j++) {//把可以去掉的因子都去了, if (fast_pow(x,ans/factor[i][0],a)==1) ans=ans/factor[i][0]; } } printf("%lld\n",ans); } return 0; }
相关文章推荐
- Description has only two Sentences HDU - 3307 欧拉定理
- hdu 3307 Description has only two Sentences 欧拉定理+快速幂
- hdu 5312 Sequence(数学推导——三角形数)
- HDU 2086 A1 = ? (找规律推导公式 + 水题)(Java版)
- HDU-5826-physics-数学推导
- HDU 4565 (数学推导 矩阵快速幂)
- HDOJ/HDU 1297 Children’s Queue(推导~大数)
- HDU 2421 Deciphering Password 公式推导
- HDU1060 Leftmost Digit (数学推导)
- HDU 5858 Hard problem (公式推导)
- HDU 5525:Product 欧拉定理
- hdu-4549(矩阵快速幂+欧拉定理)
- HDU-4919-数学推导加Java大数
- hdu 5734 Acperience(2016 Multi-University Training Contest 2——化简公式,数学推导)
- hdu 2588 GCD【欧拉+gcd推导*经典】
- HDU 2608 0 or 1(数学推导)
- HDU 4549 M斐波那契数列(矩阵快速幂+欧拉定理)
- 数学向量推导______Acperience( hdu 5734 2016多校 )
- http://acm.hdu.edu.cn/showproblem.php?pid=3307 (欧拉 + 推导公式 + gcd)
- HDU 4586 Play the Dice (数学,公式推导)