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≤nki mod n,1≤i≤n是模n的完全剩余系
其实就是让我们求一个数n的原根个数
分析:
为什么是求原根的个数呢?原根又是什么呢?
这要从头说起。。。
如果a与p互质,费马小定理告诉我们
ap−1≡1 (mod p)ap−1≡1 (mod p)
当然对于a来说,有可能存在多个i满足1≤i≤p−1,ai≡1 (mod p)1≤i≤p−1,ai≡1 (mod p)
这样一来就一定可以存在一个最小的幂次e使得 ae≡1 (mod p)ae≡1 (mod p)
我们定义这个最小指数叫a模p的次数或阶
ep(a)=(使得ae≡1 (mod p)的最小指数e≥1)ep(a)=(使得ae≡1 (mod p)的最小指数e≥1)
那么就一定会存在这样的一个a (1≤a≤p−11≤a≤p−1)
ep(a)=p−1ep(a)=p−1
我们就称这样的a为模p的原根
对于原根a来说他的幂
a,a2,a3,a4,.....ap−3,ap−2,ap−1 (mod p)a,a2,a3,a4,.....ap−3,ap−2,ap−1 (mod p)
必须都是模p不同的(既然p-1个数模p都不同那么值一定是1,2,3….p-1了)
证明:
假设有两个模p后值相同的我们取幂次i,j,1≤i<j≤p−1i,j,1≤i<j≤p−1
有ai≡aj (mod p)ai≡aj (mod p)
两边同乘ajaj的逆元
有aj−i≡1 (mod p)aj−i≡1 (mod p)
其中指数j−ij−i一定小于p−1p−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;
}