典型例题:51nod 1135 原根
设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。(其中φ(m)表示m的欧拉函数)
给出1个质数P,找出P最小的原根。
Input
输入1个质数P(3 <= P <= 10^9)
Output
输出P最小的原根。
Input示例
3
Output示例
2 欧拉公式:含义:欧拉函数就是指:对于一个正整数n,小于n且和n互质的正整数(包括1)的个数,记作φ(n)
通式:
其中p1, p2……pn为x的所有质因数,x是不为0的整数
φ(1)=1(唯一和1互质的数(小于等于1)就是1本身)
注意:每种质因数只一个。 比如12=2*2*3那么φ(12)=12*(1-1/2)*(1-1/3)=4
性质① m是素数时,有φ(m)=m-1性质② 当m、n互素时,φ(m*n)=φ(m)*φ(n)性质③ 对一切正整数n,有φ(p^n)=[p^(n-1)]*(p-1)
欧拉函数性质(持续更新):
若n是质数p的k次幂,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),因为除了p的倍数外,其他数都跟n互质。
φ(n)是积性函数,当gcd(n,m)==1时,φ(nm)=φ(n)*φ(m)
①N>1,不大于N且和N互素的所有正整数的和是 1/2*M*eular(N)。
②若(N%a==0 && (N/a)%a==0) 则有:E(N)=E(N/a)*a;
③若(N%a==0 && (N/a)%a!=0) 则有:E(N)=E(N/a)*(a-1);
费马小定理(Fermat‘s little theorem) 是数论中的一个重要定理,其内容为: 假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p),即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。
还有些定理:http://blog.csdn.net/yxuanwkeith/article/details/52387873
题目:
给定阶的含义为:设a模m的阶为k,则k满足a^k%m==1,且k最小
题解:
因为这题的p为质数,所以φ(p)=p-1,那么这题就是要找到最小的a使得a^(p-1)%p==1,且对于所有的k∈[0,p-1)都
不满足a^k%p等于1,(根据费马小定理,对于所有的正整数a,a^(p-1)%p==1一定成立)
方法就是枚举a,对于每一个a判断是否满足条件,可k的范围特别的大,枚举k不实际,那怎么办?其实我们只需要
枚举p-1的因数即可,只要p-1的所有因数都满足其不是a的阶,p-1即是a的阶
http://blog.csdn.net/acdreamers/article/details/8883285(大佬的题解)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 typedef __int64 ll; 6 7 int a[111]; 8 9 int pow_mod(int x, int n, int mod) { 10 int ret = 1; 11 while(n) { 12 if(n & 1) ret = (ll)ret*x%mod; 13 x = (ll)x*x%mod; 14 n >>= 1; 15 } 16 return ret; 17 } 18 19 int main() { 20 int n; 21 while(scanf("%d", &n) != -1){ 22 int tmp = n-1, tot = 0; 23 for(int i = 2;i*i <= tmp ;i++) if(tmp % i == 0) { 24 a[tot++] = i; 25 while(tmp % i == 0) tmp /= i; 26 } 27 if(tmp > 1) a[tot++] = tmp; 28 tmp = n-1; 29 for(int i = 2;i < n; i++) { 30 bool flag = 1; 31 for(int j = 0;j < tot; j++) { 32 if(pow_mod(i, tmp/a[j], n) == 1) { 33 flag = 0; break; 34 } 35 } 36 if(flag) { 37 printf("%d\n", i); break; 38 } 39 } 40 } 41 return 0; 42 }