hdu3307 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): 1963 Accepted Submission(s): 585

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
思考:大致过程如下图,不过还存在着细节理解得不是很透彻,留坑以后继续思考。

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
vector<pair<int,int>>p;
ll quick(ll a,ll b,ll mod){ 
    ll ans=1;  
    a=a%mod;
    while(b!=0){
        if(b&1) ans=(ans*a)%mod;
        b>>=1;
        a=(a*a)%mod;
    }
    return ans;
}
ll get_euler(ll n){ //欧拉函数 
    ll res=n,a=n;
    for (ll i = 2; i*i<=a;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;
}
void check(ll x)//分解质因数 
{
	for(ll i=2;i*i<=x;++i)
	{
		if(x%i==0)
		{
			int cnt=0;
			while(x%i==0) cnt++,x/=i;
			p.push_back({i,cnt}); 
		}
	}
	if(x>1) p.push_back({x,1});
}
int main()
{
	ll x,y,a0;
	while(scanf("%lld %lld %lld",&x,&y,&a0)!=EOF)
	{
		p.clear();
		y/=x-1;
		a0/=__gcd(y,a0);
		if(__gcd(a0,x)!=1) {//若不满足欧拉定理 
			printf("Impossible!\n");continue;
		}
		ll ans=get_euler(a0);
		check(ans);
		for(int i=0;i<p.size();++i)
		{
			for(int j=0;j<p[i].second;++j)
			if(quick(x,ans/p[i].first,a0)==1) ans/=p[i].first;
		}
		printf("%lld\n",ans);
	}
 } 
发布了283 篇原创文章 · 获赞 0 · 访问量 7323

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/104998068