首页 > 代码库 > uva 10006 数论入门题
uva 10006 数论入门题
这是一个入门的数论题目 , 只需要简单的找素数和快速幂取模
题意:输入一个数 n , 如果这个数是非素数 , 问是不是 这个2~n-1区间的所有数都满足 ?
解法:由于数据量不大 , 可以直接暴力求解
解法1: 暴力求解
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; long long prime[65010]; long long n; void init() { memset(prime , 0 , sizeof(prime)); long long i , j; for(i = 2; i < 65000 ; i++) { if(prime[i] == 0) { for(j = i+i; j < 65000; j += i) prime[j] = 1; } } } long long pow_mod(long long a) { long long x = 1 , y = a; long long z = n; while(z-1) { if(z%2 == 1) x = x*y%n; y = y*y%n; z /= 2; } x = x*y%n; return x; } int main() { init(); while(1) { long long i ; cin>>n; if(n == 0) break; if(!prime[n]) { cout<<n<<" is normal."<<endl; continue; } for(i = 2; i < n; i++) if(pow_mod(i) != i) break; if(i == n) cout<<"The number "<<n<<" is a Carmichael number."<<endl; else cout<<n<<" is normal."<<endl; } return 0; }
解法2:
利用唯一分解定理 , 任何一个非素数 , 都会由素数因子组成 , 因此当我们要求 a^n 时 ,
我们通过 a = x*y , a^n = (x^n)*(y^n) , 这时我们就只需求得 a 的一个因子 , 由此可以降低时间复杂度
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; int prime[65010]; long long n; long long gcd[65010]; long long pri[65010]; void init() { memset(prime , 0 , sizeof(prime)); long long i , j; for(i = 2; i < 65000 ; i++) { if(prime[i] == 0) { for(j = i+i; j < 65000; j += i) prime[j] = 1 , pri[j] = i; } } } long long pow_mod(long long a) { long long x = 1 , y = a; long long z = n; while(z-1) { if(z%2 == 1) x = x*y%n; y = y*y%n; z /= 2; } x = x*y%n; return x; } int main() { init(); while(1) { long long i , j , x; cin>>n; if(n == 0) break; if(!prime[n]) { cout<<n<<" is normal."<<endl; continue; } if((gcd[2] = pow_mod(2)) != 2) { cout<<n<<" is normal."<<endl; continue; } if((gcd[3] = pow_mod(3)) != 3) { cout<<n<<" is normal."<<endl; continue; } for(i = 4; i < n; i++) { if(prime[i]) { j = i/pri[i]; x = gcd[pri[i]]*gcd[j]%n; if((gcd[i] = x) != i) break; } else { gcd[i] = pow_mod(i); if(gcd[i] != i) break; } } if(i == n) cout<<"The number "<<n<<" is a Carmichael number."<<endl; else cout<<n<<" is normal."<<endl; } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。