P.S.:这玩意的证明很有意思,本蒟蒻用了一种奇葩的方式证明的,比较复杂,由于考虑到很多像我一样的蒟蒻看不懂大佬们奥妙重重的博客,于是就讲得通俗易懂一点
首先,φ(n)函数大家应该知道,就是求小于n的所有数k中,gcd(k,n)=1的所有k的个数,即φ(n)=Σ(d|n)1
然后,我们来看一下证明思路:
以12为例:
φ(1)=1
1
φ(2)=1
1
φ(3)=2
1,2
φ(4)=2
1,3
φ(6)=2
1,5
φ(12)=4
1,5,7,11
这些数字看似毫无关联,但是,让我们对其进行一些处理:
将每一个φ(d)中包含的的数都乘上n/d
我们就会得到这么一个表格:
d | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
1 | 1*12=12 | |||||||||||
2 | 1*6=6 | |||||||||||
3 | 1*4=4 | 2*4=8 | ||||||||||
4 | 1*3=3 | 3*3=9 | ||||||||||
6 | 1*2=2 | 5*2=10 | ||||||||||
12 | 1*1=1 | 5*1=5 | 7*1=7 | 11*1=11 |
我们发现每一列都有且仅有一个红块,而每行的红块个数即为该行的φ值
我们用代码来说明其正确性:
#include
using namespace std;
int main()
{
int n,i,j;
int a[1000];
for (j=1;j<=n;j++) a[j]=0;
cin >> n;
cout << " d ";
for (i=1;i<=n;i++) cout << setw(4) << i << " ";
cout << endl;
for (i=1;i<=n;i++)
{
if (n%i==0)
{
for (j=1;j<=i;j++)
if (__gcd(i,j)==1)
a[j*n/i]=1;
cout << setw(4) << i << " " ;
for (j=1;j<=n;j++)
if (a[j]==0) cout << " false ";
else cout << " true ";
cout << endl;
}
}
}
为什么能用这种方式证明呢?
让我们来分析分析:
我们先设集合A(d)表示满足φ(d)的元素
即:A(d)={q(d,1),q(d,2),......,q(d,φ(d))}
那么显然:gcd(d,q(d,i))=1
我们将A(d)中的每一种元素都乘以n/d
得到集合B(d)={x*n/d|x∈A(d)}
然后我们会发现:gcd(n,q(d,i)*n/d)=gcd(d*n/d,q(d,i)*n/d)=n/d
由上式可知:
B(d)为小于n,且与n的最大公约数为n/d的数的集合
而两个数的最大公约数是唯一的,故不可能存在重复。
又因为原式为:Σ(d|n)φ(d)
所以:
该式考虑到了n的所有约数,故不可能存在遗漏。
即全集U={1,2,3,......,n}=B(1)∪B(2)∪......∪B(n)
到了这里就显然有答案了哈~~