版权声明:欢迎转载 https://blog.csdn.net/l18339702017/article/details/81908161
2^x mod n = 1Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 19442 Accepted Submission(s): 6093 Problem Description Give a number n, find the minimum x(x>0) that satisfies 2^x mod n = 1. Input One positive integer on each line, the value of n. Output If the minimum x exists, print a line with 2^x mod n = 1. Sample Input 2 5 Sample Output 2^? mod 2 = 1 2^4 mod 5 = 1 Author MA, Xiao Source |
欧拉定理:a^x 1(mod m),那么 x = euler(m);
当gcd(n,x) > 1 或者 n ==1 的时候,不符合;否则 x = euler(n)的满足这个的最小因数;
#include <bits/stdc++.h>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
#define line cout<<"-----------------"<<endl;
typedef long long ll;
const int maxn = 1e5+10;
const int MAXN = 1e6+10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
const int N = 1010;
ll Euler(ll n){//欧拉函数模板
ll ans = 1;
for(int i = 2; i * i <= n; i++){
if(n % i == 0){
n /= i;
ans *= (i - 1);
while(n % i == 0){
n /= i;
ans *= i;
}
}
}
if(n > 1) ans *= (n-1);
return ans ;
}
ll Mul(ll x , ll y , ll mod){//快速幂取模模板
ll ans = 0;
while(y){
if(y & 1){
ans = (ans + x) % mod;
}
x = x * 2 % mod;
y >>= 1;
}
return ans ;
}
ll pow_mod(ll x , ll n , ll mod ){
ll ans = 1;
ll t = x % mod ;
while(n) {
if(n & 1){
ans = Mul(ans , t, mod);
}
t = Mul(t , t , mod);
n >>= 1 ;
}
return ans ;
}
int main(){
ll n;
while(scanf("%lld",&n)!=EOF){
if(n % 2 == 0 || n == 1){
printf("2^? mod %lld = 1\n",n);
continue;
}
ll m = Euler(n);
ll ans = 1e18;
for(ll i = 1 ; i * i <= m ; i++){
if(m % i == 0){
if(pow_mod(2 , i , n) == 1)
ans = min(ans , i);
if(pow_mod(2 , m/i , n) == 1)
ans = min(ans , m/i);
}
}
printf("2^%lld mod %lld = 1\n", ans , n);
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
#define line cout<<"-----------------"<<endl;
typedef long long ll;
const int maxn = 1e5+10;
const int MAXN = 1e6+10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
const int N = 1010;
vector<ll>ve;
void get_prime(ll n){
for(ll i = 1 ;i * i <= n;i++){
if(n % i == 0){
ve.push_back(i);
if(i * i != n)
ve.push_back(n/i);
}
}
}
ll Euler(ll n){//欧拉函数模板
ll ans = 1;
for(int i = 2; i * i <= n; i++){
if(n % i == 0){
n /= i;
ans *= (i - 1);
while(n % i == 0){
n /= i;
ans *= i;
}
}
}
if(n > 1) ans *= (n-1);
return ans ;
}
//下面两个函数相当于快速幂取模,可以防止爆long long
ll Mul(ll x , ll y , ll mod){//快速幂取模模板
ll ans = 0;
while(y){
if(y & 1){
ans = (ans + x) % mod;
}
x = x * 2 % mod;
y >>= 1;
}
return ans ;
}
ll pow_mod(ll x , ll n , ll mod ){
ll ans = 1;
ll t = x % mod ;
while(n) {
if(n & 1){
ans = Mul(ans , t, mod);
}
t = Mul(t , t , mod);
n >>= 1 ;
}
return ans ;
}
int main(){
ll n;
while(scanf("%lld",&n)!=EOF){
ve.clear();
if(n % 2 == 0 || n == 1){
printf("2^? mod %lld = 1\n",n);
continue;
}
ll ans = Euler(n);
get_prime(ans);
sort(ve.begin(),ve.end());
for(int i=0;i<ve.size();i++){
if( pow_mod(2ll,ve[i],n) == 1 ){
ans = ve[i];
break;
}
}
printf("2^%lld mod %lld = 1\n", ans , n);
}
return 0;
}