(紫书第十章)10.2.2数论中的计数问题

2021-06-04 20:38:05 星期五


约数个数:

首先讲解了一下约数个数,\(n=p_1^{a_1}p_2^{a_2}p_3^{a_3}.....p_k^{a_k}\),求n的正约数个数:
我们知道\(p_1,p_2....p_k\)\(n\)的素数因子,除此之外就\(n\)没有其他素数因子了,那么我们可以知道\(n\)的因子必将是这些素数的排列组合,例如我们可以选出\(0,1,2,3,...a_1\)\(p_1\)这有\((a_1+1)\)中选择,同理\(p_2,p_3.....p_k\)分别有\((a_2+1),(a_3+1),(a_4+1)...(a_k+1)\)种选择,然后我们知道他们互不影响所以用乘法原理得\(n\)的约数个数为:

\[\prod_{i=1}^{k}(a_i+1)=(a_1+1)*(a_2+1)*....*(a_k+1) \]

这个挺重要的,能记就记住吧,最重要是理解,20年蓝桥杯好像用到这个知识点了.

欧拉函数

之后引进欧拉函数:小于n且与n互素的整数个数\(n=p_1^{a_1}p_2^{a_2}p_3^{a_3}.....p_k^{a_k}\)求小于n且与n互素的数的个数.
首先我们要求与n互素的个数,那么换种思路,用容斥定理的思想来看,我们只需要用总数n减去\(p_1,p_2,....p_k\)的倍数的个数即可.即\(n-\frac{n}{p_1}-\frac{n}{p_2}-.....-\frac{n}{p_k}\),然后加上两个素数乘积的倍数的个数,(有点绕, 但是理解容斥定理,就肯定能懂)

然后经过公式的转化(比较难,作者也不太会)
就变成了我们常见的欧拉函数:

\[\phi(n)==n(1-\frac{1}{p_1})(1-\frac{1}{p_2})...(1-\frac{1}{p_k}) \]

那么我们只需要求出小于n的素数,然后算一下即可,也可借助筛法,直接求出.我去翻翻我之前写的.(静等)等不及自己动手也可.
之后说一个例题:Send a Table

题意

给出你n让你求出共多少对gcd(i,j)==1,(i<=n,j<=n) 问你共多少对:(i,j)与(j,i)当(i!=j)时算两对.

思路:

其实这个就是欧拉函数的一个应用,直接求出\(phi(2)+phi(3)+...phi(n)\)乘以2+1即可.
为什么那,我们固定一个x吧,那么小于x的欧拉函数有\(phi(x)\)个同理反过来固定y就有\(phi(y)\)个最后加上1是因为(1,1); (当然也可以把1算上phi最后别忘了减1就行.)

ll phi[maxn];
void p(){
	phi[1]=1;
	for(int i=2;i<=50000;i++){
		if(!a[i]){
			vis[++cnt]=i;
			phi[i]=i-1;
		}
		for(int j=1;j<=cnt&&vis[j]*i<=50000;j++){
			a[i*vis[j]]=1;
			if(i%vis[j]==0){
				phi[i*vis[j]]=phi[i]*vis[j];
				break;
			}else {				
				phi[i*vis[j]]=phi[i]*(vis[j]-1);
			}
		}
	}
	for(int i=1;i<=50000;i++){
		phi[i]+=phi[i-1];
	}
}
void solve()
{
    printf("%lld\n",phi[n]*2-1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值