一些重要的数论函数+线性筛模板

数论这块其实有好多函数,挺让人头疼的。

本篇主要讲解一些数论函数(欧拉函数、约数个数、约数和、莫比乌斯函数)以及它们的线性筛求法。

1.欧拉函数 φ(n)

欧拉函数φ(n)表示比n小的、且与n互质的正整数的数量。

如果把n分解成若干质因数之积的形式:n=(p1^a1)*(p2^a2)*...*(pk^ak)的话:

φ(n)=n*(1-1/p1)*(1-1/p2)*...*(1-1/pk)。

显然把不互质的都减掉,剩下的就是互质的。

这个可以通过分解质因数在O(sqrt(n))的时间内算出来。

线性筛法:

代码里我用phi表示欧拉函数。

计算的时候只需记录phi[n]即可。

可以把n*(1-1/p1)*(1-1/p2)*...*(1-1/pk)里的n拆成(p1^a1)*(p2^a2)*...*(pk^ak)分别乘进括号里。

这么说如果某质数p只有一次幂,贡献就是p-1(n拆分出来的一个p进括号,和1-1/p相乘后的结果)。

否则(p出现了多次),除了第一次是p-1,剩下的几次都是p(1-1/p已经用过了,没有东西能跟p相乘约掉了)。

显然i%pr[j]!=0的时候代表(i*pr[j])这个数中pr[j]只有一次幂。这样就能判断某个p是否是第一次出现了。

 1 phi[1]=1;
 2 for(int i=2;i<=n;i++)
 3 {
 4     if(!vis[i])
 5     {
 6         phi[i]=i-1;
 7         pr[++pc]=i;
 8     }
 9     for(int j=1;j<=pc&&i*pr[j]<=n;j++)
10     {
11         vis[i*pr[j]]=1;
12         if(i%pr[j])
13         {
14             phi[i*pr[j]]=phi[i]*(pr[j]-1);
15         }else
16         {
17             phi[i*pr[j]]=phi[i]*pr[j];
18             break;
19         }
20     }
21 }

2.约数个数 d(n)

n=(p1^a1)*(p2^a2)*...*(pk^ak)

则n的约数个数d(n)=(a1+1)*(a2+1)*...*(ak+1)。

对于某个质因数pi,某个约数要么包含少于ai个pi,要么不包含pi。

所以每对括号内,"1"表示如果不包含pi则只有一种选法(即不选pi)。

而ai表示如果选pi,有ai种选法(选1个、选2个、选3个......选ai个,共ai种选法)。

所以把每对括号乘到一起就是选法总数。每个选法都能乘出一个约数,所以选法总数就是约数个数。

这个式子其实有点类似母函数(生成函数)。

考虑怎么线性筛出来:

开一个辅助数组记录最小因子的幂次,即ai。

当i和pr[j]互质的时候,i的任意因数和pr[j]的任意因数相乘都能组成i*pr[j]的一个因数。

当i和pr[j]不互质的时候,我们算到i的时候,认为某个因子只有a个,而到i*pr[j]这个数的时候,有a+1个了。

所以我们把d[i]中的(a+1)除掉,再乘以(a+2)即可。

 1 d[1]=1;
 2 for(int i=2;i<=n;i++)
 3 {
 4     if(!vis[i])
 5     {
 6         d[i]=2;
 7         exp[i]=1;
 8         pr[++pc]=i;
 9     }
10     for(int j=1;j<=pc&&i*pr[j]<=n;j++)
11     {
12         vis[i*pr[j]]=1;
13         if(i%pr[j])
14         {
15             d[i*pr[j]]=d[i]*d[pr[j]];
16             exp[i*pr[j]]=1;
17         }else
18         {
19             d[i*pr[j]]=d[i]/(exp[i]+1)*(exp[i]+2);
20             exp[i*pr[j]]=exp[i]+1;
21             break;
22         }
23     }
24 }

3.约数和 σ(n)

σ(n)表示n的所有约数之和。

若把n分解为n=(p1^a1)*(p2^a2)*...*(pk^ak),

则σ(n)=(1+p1+p1^2+p1^3+...+p1^a1)*(1+p2+p2^2+p2^3+...+p2^a2)*...*(1+pk+pk^2+pk^3+...+pk^ak)。

这个式子的证明也很显然,跟约数个数的那个很像,也是类似母函数的想法,比较简单。

这个式子括号都拆开之后的每一项都是n的一个因数嘛,当然就是要加到一起喽。

线性筛出来稍稍有些麻烦。

代码中我用sig(sigma太长了,我看着别扭...)表示约数和。

开两个数组pw和spw辅助计算,pw相当于上式的pi^ai,即pi的最高次幂的值。

spw相当于(1+pi+pi^2+...+pi^ai)。

其它的想法就都跟约数个数差不多了。

 1 sig[1]=1;
 2 for(int i=2;i<=n;i++)
 3 {
 4     if(!vis[i])
 5     {
 6         pw[i]=i;
 7         spw[i]=i+1;
 8         sig[i]=i+1;
 9         pr[++pc]=i;
10     }
11     for(int j=1;j<=pc&&i*pr[j]<=n;j++)
12     {
13         vis[i*pr[j]]=1;
14         if(i%pr[j])
15         {
16             pw[i*pr[j]]=pr[j];
17             spw[i*pr[j]]=pr[j]+1;
18             sig[i*pr[j]]=sig[i]*sig[pr[j]];
19         }else
20         {
21             pw[i*pr[j]]=pw[i]*pr[j];
22             spw[i*pr[j]]=spw[i]+pw[i]*pr[j];
23             sig[i*pr[j]]=sig[i]/spw[i]*spw[i*pr[j]];
24             break;
25         }
26     }
27 }

4.莫比乌斯函数 μ(n)

这个基本上做莫比乌斯反演的时候用的很多......

然而pengzhou讲完了莫比乌斯反演之后我还没怎么做那个的题......

下面我用mu(n)表示莫比乌斯函数μ(n)。

莫比乌斯函数,mu(1)=1。

n存在平方因子时,mu(n)=0。

其余情况:即n=p1*p2*p3*...*pk(其中pi为质数)时,mu(n)=(-1)^k。

即当n不等于1、又没有平方因子时,根据n的质因子个数的奇偶性判断,是奇数则mu(n)为-1、是偶数则mu(n)为1。

线性筛的时候很简单,质数的mu为-1,遇到平方因子则为0。不是平方因子的,反转正负性即可。

 1 mu[1]=1;
 2 for(int i=2;i<=n;i++)
 3 {
 4     if(!vis[i])
 5     {
 6         mu[i]=-1;
 7         pr[++pc]=i;
 8     }
 9     for(int j=1;j<=pc&&i*pr[j]<=n;j++)
10     {
11         vis[i*pr[j]]=1;
12         if(i%pr[j])
13         {
14             mu[i*pr[j]]=-mu[i];
15         }else
16         {
17             mu[i*pr[j]]=0;
18             break;
19         }
20     }
21 }

最后放个四合一(虽然可能永远也用不到四合一):

 1 phi[1]=d[1]=sig[1]=mu[1]=1;
 2 for(int i=2;i<=n;i++)
 3 {
 4     if(!vis[i])
 5     {
 6         phi[i]=i-1;
 7         d[i]=2;
 8         exp[i]=1;
 9         pw[i]=i;
10         spw[i]=i+1;
11         sig[i]=i+1;
12         mu[i]=-1;
13         pr[++pc]=i;
14     }
15     for(int j=1;j<=pc&&i*pr[j]<=n;j++)
16     {
17         vis[i*pr[j]]=1;
18         if(i%pr[j])
19         {
20             phi[i*pr[j]]=phi[i]*(pr[j]-1);
21             d[i*pr[j]]=d[i]*d[pr[j]];
22             exp[i*pr[j]]=1;
23             pw[i*pr[j]]=pr[j];
24             spw[i*pr[j]]=pr[j]+1;
25             sig[i*pr[j]]=sig[i]*sig[pr[j]];
26             mu[i*pr[j]]=-mu[i];
27         }else
28         {
29             phi[i*pr[j]]=phi[i]*pr[j];
30             d[i*pr[j]]=d[i]/(exp[i]+1)*(exp[i]+2);
31             exp[i*pr[j]]=exp[i]+1;
32             pw[i*pr[j]]=pw[i]*pr[j];
33             spw[i*pr[j]]=spw[i]+pw[i]*pr[j];
34             sig[i*pr[j]]=sig[i]/spw[i]*spw[i*pr[j]];
35             mu[i*pr[j]]=0;
36             break;
37         }
38     }
39 }

 

转载于:https://www.cnblogs.com/eternhope/p/9885357.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧农业是一种结合了现代信息技术,包括物联网、大数据、云计算等,对农业生产过程进行智能化管理和监控的新模式。它通过各种传感器和设备采集农业生产中的关键数据,如大气、土壤和水质参数,以及生物生长状态等,实现远程诊断和精准调控。智慧农业的核心价值在于提高农业生产效率,保障食品安全,实现资源的可持续利用,并为农业产业的转型升级提供支持。 智慧农业的实现依赖于多个子系统,包括但不限于设施蔬菜精细化种植管理系统、农业技术资料库、数据采集系统、防伪防串货系统、食品安全与质量追溯系统、应急追溯系统、灾情疫情防控系统、农业工作管理系统、远程诊断系统、监控中心、环境监测系统、智能环境控制系统等。这些系统共同构成了一个综合的信息管理和服务平台,使得农业生产者能够基于数据做出更加科学的决策。 数据采集是智慧农业的基础。通过手工录入、传感器自动采集、移动端录入、条码/RFID扫描录入、拍照录入以及GPS和遥感技术等多种方式,智慧农业系统能够全面收集农业生产过程中的各种数据。这些数据不仅包括环境参数,还涵盖了生长状态、加工保存、检验检疫等环节,为农业生产提供了全面的数据支持。 智慧农业的应用前景广阔,它不仅能够提升农业生产的管理水平,还能够通过各种应用系统,如库房管理、无公害监控、物资管理、成本控制等,为农业生产者提供全面的服务。此外,智慧农业还能够支持政府监管,通过发病报告、投入品报告、死亡报告等,加强农业产品的安全管理和质量控制。 面对智慧农业的建设和发展,存在一些挑战,如投资成本高、生产过程标准化难度大、数据采集和监测的技术难题等。为了克服这些挑战,需要政府、企业和相关机构的共同努力,通过政策支持、技术创新和教育培训等手段,推动智慧农业的健康发展。智慧农业的建设需要明确建设目的,选择合适的系统模块,并制定合理的设备布署方案,以实现农业生产的智能化、精准化和高效化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值