Love you Ten thousand years
Love you Ten thousand years------Earth's rotation is a day that is the representative of a day I love you. True love, there is no limit and no defects. Earth's revolution once a year, it is on behalf of my love you more than a year. Permanent horizon, and my heart will never change ……
We say that integer x, 0 < x < n,(n is a odd prime number) is a LovePoint-based-on n if and only if the set { (x i mod n) | 1 <= i <= n-1 } is equal to { 1, ..., n-1 }. For example, the powers of 3 modulo 7 are 3, 2, 6, 4, 5, 1, and thus 3 is a LovePoint-based-on 7.
Now give you a integer n >= 3(n will not exceed 2 31).
We say the number of LovePoint-based-on n is the number of days the earth rotating.
Your task is to calculate the number of days someone loved you.
Input
Each line of the input contains an integer n. Input is terminated by the end-of-file.
Output
For each n, print a single number that gives the number of days someone loved you.
Sample Input
5
Sample Output
2
题意:
让我们求出小于n的数的个数,满足 ki mod n,1≤i≤n k i m o d n , 1 ≤ i ≤ n 是模n的完全剩余系
其实就是让我们求一个数n的原根个数
分析:
为什么是求原根的个数呢?原根又是什么呢?
这要从头说起。。。
如果a与p互质,费马小定理告诉我们
ap−1≡1 (mod p) a p − 1 ≡ 1 ( m o d p )
当然对于a来说,有可能存在多个i满足 1≤i≤p−1,ai≡1 (mod p) 1 ≤ i ≤ p − 1 , a i ≡ 1 ( m o d p )
这样一来就一定可以存在一个最小的幂次e使得 ae≡1 (mod p) a e ≡ 1 ( m o d p )
我们定义这个最小指数叫a模p的次数或阶
ep(a)=(使得ae≡1 (mod p)的最小指数e≥1) e p ( a ) = ( 使 得 a e ≡ 1 ( m o d p ) 的 最 小 指 数 e ≥ 1 )
那么就一定会存在这样的一个a ( 1≤a≤p−1 1 ≤ a ≤ p − 1 )
ep(a)=p−1 e p ( a ) = p − 1
我们就称这样的a为模p的原根
对于原根a来说他的幂
a,a2,a3,a4,.....ap−3,ap−2,ap−1 (mod p) a , a 2 , a 3 , a 4 , . . . . . a p − 3 , a p − 2 , a p − 1 ( m o d p )
必须都是模p不同的(既然p-1个数模p都不同那么值一定是1,2,3….p-1了)
证明:
假设有两个模p后值相同的我们取幂次 i,j,1≤i<j≤p−1 i , j , 1 ≤ i < j ≤ p − 1
有 ai≡aj (mod p) a i ≡ a j ( m o d p )
两边同乘 aj a j 的逆元
有 aj−i≡1 (mod p) a j − i ≡ 1 ( m o d p )
其中指数 j−i j − i 一定小于 p−1 p − 1
矛盾,故命题得证
原根定理:
每个素数p都有原根,有恰好 ϕ(p−1) ϕ ( p − 1 ) 个模p的原根
对于一般情况所有的数m来说并不一定有原根,但当模m有原根时,可以其原根个数为 ϕ(ϕ(m)) ϕ ( ϕ ( m ) )
(和费马小定理推广为欧拉定理类似)
以上均为现成的定理,这里不再一一证明,以后会专门证明这些定理
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int Euler(int n){
int ans = n;
for(int i = 2; i * i <= n; i++){
if(n % i == 0){
ans = ans / i * (i - 1);
while(n % i == 0) n /= i;
}
}
if(n > 1) ans = ans / n * (n - 1);
return ans;
}
int main(){
int n;
while(~scanf("%d",&n)){
printf("%d\n",Euler(Euler(n)));
}
return 0;
}