zoukankan      html  css  js  c++  java
  • 数论总结


    持续更新~~

    本篇博客包含了本蒟蒻学的数论知识点(qwq)

    需要有一定基础


    欧几里得算法

    欧几里得算法,用于计算两个整数的最大公约数

    对于两个数(a,b),我们定义(gcd(a,b))表示它们的最大公约数

    为了比较快的求出最大公约数,有了以下引理:

    [gcd(a,b)=gcd(b,a\%b) ]

    证明:

    我们设(a=xc,b=yc)其中(x,y)互质

    那么(c)自然就是(a,b)最大公约数

    (a\%b=(x-ky)c)

    此时我们发现(x-ky,y)互质,证明:

    假设(x-ky,y)不互质,设(y=np,x-ky=mp)其中(n,m)互质

    (y=np)代入(x-ky=mp)得:

    [x-knp=mp ]

    [x=p(kn+m) ]

    那么我们发现此时(x,y)不互质,有公约数(p),与最上面的假设相反,所以(x-ky,y)互质

    那么上文提及(b=yc,a\%b=(x-ky)c)

    (y,x-ky)互质

    所以(b,a\%b)的最大公约数为(c)

    所以(gcd(a,b)=gcd(b,a\%b)=c)

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int a,b;
    int Get_gcd(int a,int b)
    {
    	return b?Get_gcd(b,a%b):a;
    }
    int main()
    {
    	scanf("%d%d",&a,&b);
    	printf("gcd(%d,%d)=%d
    ",a,b,Get_gcd(a,b));
    	return 0;
    }
    

    扩展欧几里得算法

    扩展欧几里得算法,一般用来求解不定方程,求解线性同余方程,求解模的逆元

    引理:有一组(x,y)使得:(gcd(a,b)=ax+by)

    证明:

    ((1))、对于(b=0)的情况,(gcd(a,b)=a),那么此时(x=1,y=0)

    ((2))、对于(b!=0)的情况,我们根据欧几里得算法设:

    [ax+by=gcd(a,b)=gcd(b,a\%b)=bx_2+a\%b imes y_2 ]

    因为(a\%b=a-a/b*b)

    所以上式变形为:

    [ax+by=bx_2+(a-a/b imes b)y_2 ]

    [ax+by=bx_2+ay_2-a/b imes by_2 ]

    [ax+by=ay_2+bx_2-a/b imes by_2 ]

    [ax+by=ay_2+b(x_2-a/b imes y_2) ]

    那么我们发现每一层的情况都能由下一层递归得到,边界则为(b=0)

    那么代码如下:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int a,b,x,y,x1,y1;
    void Exgcd(int a,int b)
    {
    	if(!b)
    	{
    		x=1;
    		y=0;
    		return;
    	}
    	Exgcd(b,a%b);
    	x1=y;
    	y1=x-a/b*y;
    	x=x1;
    	y=y1;
    }
    int main()
    {
    	printf("a,b=");
    	scanf("%d%d",&a,&b);
    	Exgcd(a,b);
    	printf("gcd(%d,%d)=%da+%db",a,b,x,y);
    	return 0;
    }
    

    欧拉定理

    定理:若正整数(a,n)互质,则$$a^{φ(n)}≡1 (mod n)$$

    证明:

    设集合(X_1,X_2,……,X_{φ(n)})(1)(n-1)中与(n)互质的数

    那么我们思考下列数的性质:

    [aX_1,aX_2,……,aX_{φ(n)} ]

    ((1))、集合中任意两个数模(n)余数一定不同

    证明(反证法):

    假设有 $$aX_1≡aX_2 (mod n)$$

    那么必须存在

    [aX_1-aX_2≡0 (mod n) ]

    [a(X_1-X_2)≡0 (mod n) ]

    但是我们发现(a,n)互质,而(X_1-X_2)(n)小,根据唯一分解定理可以得出上式不成立

    于是我们得出结论:集合中任意两个数模(n)余数一定不同

    ((2))、集合中任意数模(n)(n)互质

    证明:

    首先,(a,n)互质,(X_1,n)互质,那么容易得出(aX_1,n)互质,那么得到:

    [gcd(aX_1,n)=1 ]

    运用欧几里得算法得到:

    [gcd(n,aX_1\%n)=1 ]

    也就是(aX_1\%n,n)互质

    于是就得到了集合中任意数模(n)(n)互质

    那么对于下面集合

    [aX_1\%n,aX_2\%n,……,aX_{φ(n)}\%n ]

    我们发现这个集合其实排序后就是:

    [X_1,X_2,……,X_{φ(n)} ]

    因为那个集合数字满足取值范围在(1)(n-1)之间(模了(n)),并且每个数与(n)互质,且两两不同,并且有(φ(n))个数(性质(1),性质(2)),这不正是上面这个集合的性质吗?

    那么:

    [aX_1 imes aX_2 imes …… imes aX_{φ(n)}≡X_1 imes X_2 imes …… imes X_{φ(n)} (mod n) ]

    变形:

    [(a^{φ(n)}-1)X_1 imes X_2 imes …… imes X_{φ(n)}≡0 (mod n) ]

    (X_1 imes X_2 imes …… imes X_{φ(n)})(n)互质,那么说明

    [a^{φ(n)}-1≡0 (mod n) ]

    [a^{φ(n)}≡1 (mod n) ]

    欧拉定理得证


    费马小定理

    定理:对于质数(p),任意整数(a),均满足:(a^p≡a (mod p))

    证明:

    我们把式子稍微变形一下:

    [a^{p-1} imes a≡a (mod p) ]

    [a^{p-1}≡1 (mod p) ]

    根据欧拉定理得到:

    [a^{φ(p)}≡1 (mod p) ]

    由于(p)是质数,所以(φ(p)=p-1),那么上式变为:

    [a^{p-1}≡1 (mod p) ]

    于是变回:

    [a^p≡a (mod p) ]

    费马小定理得证


    乘法逆元

    这个东西以前以为是个什么高级的东西。。。

    定义:

    如果 (a imes xequiv 1 (mod p))并且(gcd(a,p)=1)(a,p互质)的话,我们称(x)(a)在模(p)意义下的乘法逆元

    求解乘法逆元方法(1):费马小定理

    (p)满足是质数的时候,我们可以用费马小定理来求解乘法逆元

    费马小定理((p)为质数):

    [a^pequiv a (mod p) ]

    我们变形一下:

    [a imes a^{p-2}equiv 1 (mod p) ]

    所以当(p)是质数的时候,(a)在模(p)意义下的乘法逆元为(a^{p-2}),套一个快速幂即可

    这个方法对于单个查询,且(p)是质数的时候适用

    方法(2):扩展欧几里得

    我们首先观察一下式子:$$a imes xequiv 1 (mod p)$$

    我们把它变一下也就是$$a imes x-y imes p=1$$

    我们为了便于观看,把p用b代替,也就是:$$a imes x-b imes y=1$$

    也就是说我们只要满足上面这个式子,那么(x)就是(a)在模(b)意义下的乘法逆元,同样的(y)就是(b)在模(a)意义下的乘法逆元

    这个方法适用于单个查询

    方法(3):线性算法

    首先,我们知道$$1^{-1}equiv 1 (mod p)$$

    我们假定(p=k imes i+r(0<r<i<p))

    那么我们把这个式子放在((mod p))的意义下:$$k imes i+requiv 0 (mod p)$$

    两边都乘上(i^{-1} imes r^{-1})得:$$k imes r{-1}+i{-1}equiv 0 (mod p)$$

    [i^{-1}equiv -k imes r^{-1} (mod p) ]

    (k,r)替换一下:$$i^{-1}equiv -leftlfloorfrac{p}{i} ight floor imes (p mod i)^{-1} (mod p)$$

    这样的话,我们就可以由前面的逆元推出后面的逆元了

    这种方法适用于求一连串相邻数的逆元

    例题:洛谷P3811

    代码:

    #include<iostream>
    #include<cstdio>
    #define int long long
    #define N 3000000
    using namespace std;
    int n,p;
    int inv[N];
    signed main()
    {
    	scanf("%lld%lld",&n,&p);
    	inv[1]=1;
    	for(int i=2;i<=n;++i)
    		inv[i]=((p-p/i)*inv[p%i])%p;
    	for(int i=1;i<=n;++i)
    		printf("%lld
    ",inv[i]);
    	return 0;
    }
    

    方法(4):线性算法(2)

    以下式子都在模(p)意义下进行

    我们先算出(a_i)的前缀积:$$s[i]=s[i-1] imes a_i$$

    我们发现只要算出每一个前缀积的逆元(t_i),每一个(a_i)的逆元都好求了:$$a_i^{-1}=t_i imes s_{i-1}$$

    那么怎么求每一个前缀积的逆元呢,我们可以先把(t_n)运用费马小定理求出来: $$t_n=s_n^{p-2}$$

    再根据:$$t_i=t_{i+1} imes a_{i+1}$$

    递推出所有的(t)

    这个方法适用于求给出一串无规则的数的逆元

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define int long long
    #define N 5000007
    using namespace std;
    int n,p,k;
    int s[N],a[N],inv[N],inv_s[N];
    int qpow(int a,int b)
    {
    	int ans=1,res=a;
    	while(b)
    	{
    		if(b&1)
    			ans=(ans*res)%p;
    		res=(res*res)%p;
    		b/=2;
    	}
    	return ans%p;
    }
    signed main()
    {
    	scanf("%lld%lld",&n,&p);
    	s[0]=1;
    	for(int i=1;i<=n;++i)
    	{
    		scanf("%lld",&a[i]);
    		s[i]=(s[i-1]*a[i])%p;
    	}
    	inv_s[n]=qpow(s[n],p-2);
    	for(int i=n-1;i>=1;--i)
    		inv_s[i]=(inv_s[i+1]*a[i+1])%p;
    	for(int i=n;i>=1;--i)
    		inv[i]=(inv_s[i]*s[i-1])%p;
    	for(int i=1;i<=n;++i)
    		printf("%lld
    ",inv[i]); 
    	return 0;
    }
    

    拓展:求阶乘逆元

    定义(inv[i])(i!)的逆元

    首先我们知道:$$inv[i+1]=frac{1}{i+1!}$$

    两边同时乘(i+1)得:$$inv[i+1] imes (i+1)=frac{1}{i!}=inv[i]$$

    所以我们只要先求出(inv[n])然后往回递推出来就(ok)


    欧拉函数

    定义:

    (φ(n))表示(1)(n)中,与(n)互质的数的个数

    特殊的(φ(1)=1)

    (φ(n)=n imes prodlimits_{i=1}^k(1-frac{1}{p_i})),其中(p_i)表示(n)的质因数

    证明:

    因为每一个质因数(p_i)的倍数在(n)中都是均匀分布的,所以在(n)中会有(n imes frac{1}{p_i})(p_i)的倍数,那么其余的就是(n imes (1-frac{1}{p_i}))个,每个质因数都是如此,那么最后不是所有质因数的倍数的自然就是与(n)互质的数,也就是(n imes prodlimits_{i=1}^k(1-frac{1}{p_i}))

    积性函数

    对于一个函数(F(x)),如果(m,n)互质,满足(F(m) imes F(n)=F(m imes n))的话,这个函数叫做积性函数,如果(m,n)不互质,而是任意整数满足上式的话被叫做完全积性函数

    性质:

    (1)、当(p)为质数时,(φ(p)=p-1)

    证明:。。。看看定义就知道吧

    (2)、当(p)为质数时,(φ(p^k)=p^k-p^{k-1})

    证明:因为(p)为质数,所以:$$φ(pk)=pk imes (1-frac{1}{p})$$

    因为(p^k)只有(p)这一个质因数

    括号去掉就是性质(2)

    (3)、欧拉函数是积性函数但不是完全积性函数,对于(m,n)互质时,有(φ(m) imes φ(n)=φ(m imes n))

    (4)、当(n>2)时,(φ(n))为偶数

    证明:这个是有一个基本事实:(gcd(n,p)=1,gcd(n,n-p)=1),也就是说与(n)互质的数是成对出现的,所以(φ(n))为偶数

    (5)、对于小于(n)且与(n)互质的数,总和(=φ(n) imes n/2)

    证明:上面已经说明了与(n)互质的数是成对出现的,每一对与(n)互质的数的平均数为((p+n-p)/2),也就是(n/2),一共有(φ(n))个与(n)互质的数,所以总和为(φ(n) imes n/2)

    (6)(n=sumlimits_{d|n}φ(d))

    证明:设$$F(n)=sumlimits_{d|n}φ(d)$$

    对于互质的两个数(m,n):$$F(n) imes F(m)=sumlimits_{i|m}φ(i) imes sumlimits_{j|n}φ(j)$$

    [=φ(i_1) imes φ(j_1)+φ(i_1) imes φ(j_2)+cdots +φ(i_{km}) imes φ(j_{kn}) ]

    因为欧拉函数是积性函数,而(m,n)互质,所以它们的所有因数都互质,所以得到:

    [φ(i_1 imes j_1)+φ(i_1 imes j_2)+cdots +φ(i_{km} imes j_{kn}) ]

    我们发现(i_1 imes j_1,i_1 imes j_2,cdots,i_{km} imes j_{kn})刚好就是(m imes n)的所有因数,所以得到:

    [sumlimits_{k|m imes n} φ(k) ]

    [=F(m imes n) ]

    所以我们证明了(F(n))函数是积性函数

    那么对于任何一个质数(p),我们要求(F(p^k))的时候怎么求呢?

    因为(p^k)的因数只有(1,p,p^2,cdots,p^k),我们运用性质(2)

    [F(p^k) ]

    [=φ(1)+φ(p)+cdots+φ(p^k) ]

    [=1+(p-1)+(p^2-p)+cdots+(p^k-p^{k-1}) ]

    [=p^k ]

    我们把(n)进行质因数分解,会得到很多质数,而它们的(F)函数就等于本身,所以:

    [F(n)=F(p_1^{k_1}) imes F(p_2^{k_2}) imes cdots imes F(p_m^{k_m}) ]

    [=p_1^{k_1} imes p_2^{k_2} imes cdots imes p_m^{k_m} ]

    [=n ]

    求欧拉函数

    单个:(2-sqrt n)扫一遍就好了,素数怎么求这个就怎么求

    要是求<=n所有数的欧拉函数呢?

    埃拉托斯特尼筛求欧拉函数 (O(n(log(n))(loglogn)))

    就是普通的找质数,把倍数都筛一遍(质因数的贡献)

    void Euler(int n)
    {
        for(int i=1;i<=n;++i) 
            phi[i]=i;
        for (int i=2;i<=n;++i)
            if (phi[i]==i)//i是质数
                for (int j=i;j<=n;j+=i)//把i的倍数筛一遍
                    phi[j]=phi[j]/i*(i-1);
    }
    

    欧拉筛求欧拉函数 (O(n))

    先来了解一下欧拉筛

    for(int i=2;i<=n;++i)
    {
        if(!vis[i])//不是目前找到的素数的倍数 
            prime[cnt++]=i;//找到素数~ 
        for(int j=0;j<cnt&&i*prime[j]<=n;++j)
        {
            vis[i*prime[j]]=true;//找到的素数的倍数不访问 
            if(i%prime[j]==0) 
                break;//关键!!!! 
        }
    }
    
    

    很多人对 (if(i\% prime[j]==0)) 这一句都不太理解

    找到一种很好的解释:
    (i)(prime[j])的倍数时,(i=k∗prime[j]),如果继续运算 (j+1)(i∗prime[j+1]=prime[j]∗k∗prime[j+1])
    这里(prime[j])是最小的素因子,当(i=k∗prime[j+1])时会重复
    这里是利用最小素因子优化,使得欧拉筛达到了优秀的线性(O(n))

    下面正式求欧拉函数啦

    void Euler(int n)
    {
        phi[1]=1;//1要特判 
        for (int i=2;i<=n;i++)
        {
            if(flag[i]==0)//这代表i是质数 
            {
                prime[++num]=i;
                phi[i]=i-1;
            }
            for (int j=1;j<=num&&prime[j]*i<=n;j++)//经典的欧拉筛写法 
            {
                flag[i*prime[j]]=1;//先把这个合数标记掉 
                if (i%prime[j]==0)
                {
                    phi[i*prime[j]]=phi[i]*prime[j];//若prime[j]是i的质因子,则根据计算公式,i已经包括i*prime[j]的所有质因子 
                   break;//经典欧拉筛的核心语句,这样能保证每个数只会被自己最小的因子筛掉一次 
                }
                else 
                    phi[i*prime[j]]=phi[i]*phi[prime[j]];//利用了欧拉函数是个积性函数的性质 
            }
        }
    }
    

    狄利克雷卷积

    数论函数

    数论函数亦称算术函数,一类重要的函数,指定义在正整数集上的实值或复值函数,更一般地,也可把数论函数看做是某一整数集上定义的函数

    运算

    定义两个数论函数的加法为逐项相加,即: $$(f+g)(n)=f(n)+g(n)$$

    定义两个数论函数的乘法为这个数与每一项相乘,即: $$(x imes f)(n)=x imes f(n)$$

    狄利克雷卷积

    如下:$$t(n)=sumlimits_{i|n}f(i)g(frac{n}{i})$$

    性质

    (1)、交换律: $$f imes g=g imes f$$

    (2)、结合律:$$(f imes g) imes h=f imes (g imes h)$$

    (3)、分配率:$$(f+g) imes h=f imes h+g imes h$$

    (4)(t)是积性函数

    证明:设(n=a imes b),且(gcd(a,b)=1)

    [t(n)=sumlimits_{i|a,j|b} f(i imes j)g(frac{a}{i} imes frac{b}{j}) ]

    [=sumlimits_{i|a,j|b} f(i)g(frac{a}{i})f(j)g(frac{b}{j}) ]

    [=sumlimits_{i|a} f(i)g(frac{a}{i}) sumlimits_{j|b} f(j)g(frac{b}{j}) ]

    [=t(a) imes t(b) ]


    莫比乌斯反演

    对于两个函数(F(n))(f(n))如果满足:$$F(n)=sumlimits_{d|n}f(d)$$

    通过莫比乌斯反演会得到:$$f(n)=sumlimits_{d|n} mu (d)F(frac{n}{d})$$

    为什么呢?我们先来了解一下上面的(mu)函数

    莫比乌斯函数

    [mu (n) ]

    (1)、当(n=1)时,(mu (1)=1)

    (2)、当(n>=2)

    ((1))(d=prodlimits_{i=1}^k p_i) (p_i)为互异素数,(mu (n)=(-1)^k)

    ((2))、当上面(p_i)不互异时,也就是至少有大于等于一次方的质因数时,(mu (n)=0)

    所以莫比乌斯函数的性质就出来了:$$sumlimits_{d|n} mu (d)=[n=1]$$

    证明莫比乌斯反演

    因为性质$$sumlimits_{d|n} mu (d)=[n=1]$$

    化成狄利克雷卷积形式为:$$mu imes I=epsilon$$

    那么我们把莫比乌斯反演的式子拿过来:$$F(n)=sumlimits_{d|n} f(d)$$

    化成狄利克雷卷积形式为:$$F=f imes I$$

    两边都乘上(mu)为:$$F imes mu =f imes I imes mu$$

    也就是:$$F imes mu =f imes epsilon$$

    也就是:$$f=mu imes F$$

    化回来就是:$$f(n)=sumlimits_{d|n} mu (d) imes F(frac{n}{d})$$


    整除分块

    这是一个很神奇的方法,可以把很多数论中的(O(n))的优秀复杂度优化成更优秀的(O(sqrt n))

    例如下面的式子:$$sumlimits_{i=1}^n leftlfloor frac{n}{i} ight floor $$

    我们本来是可以直接一次循环(O(n))算出的,但是有些题目可能会卡,所以更优秀的算法出来了

    我们发现对于一部分连串的(i)(frac{n}{i})会相同

    例如当(n=11)时,(i=6,7,8,9,10,11)的时候(frac{n}{i})都等于(1)

    所以我们可以分一块一块来做

    下面是代码:

    int Get(int x)
    {
    	int ans=0;
    	for(int i=1,j;i<=x;i=j+1)
    	{
    		j=x/(x/i);
    		ans+=(x/i)*(j-i+1);
    	}
    	return ans;
    }
    

    据说上面的复杂度是(O(sqrt n)),然而我太弱了,不会证,姑且用着吧~~~


    莫比乌斯函数与欧拉函数的关系

    [frac{φ(n)}{n}=sumlimits_{d|n} frac{mu (d)}{d} ]

    其实应该放在上面的,但是学习没有学全面,现在才学到

    首先,我们知道:$$sumlimits_{d|n} φ(d)=n$$

    变形:$$sumlimits_{d|n} φ(d)=id(n)$$

    变成狄利克雷卷积形式就是:$$φ imes I=id$$

    我们两边都乘上(mu):$$φ imes I imes mu=id imes mu$$

    我们知道(I imes mu =epsilon),带入:$$φ=id imes mu$$

    化回来:$$φ(n)=sumlimits_{d|n} mu (d) id(frac{n}{d})$$

    [φ(n)=sumlimits_{d|n} mu (d) frac{n}{d} ]

    [frac{φ(n)}{n}=sumlimits_{d|n} frac{mu (d)}{d} ]


    杜教筛

    假设我们要求一个式子,其中(f)为积性函数:$$S(n)=sumlimits_{i=1}^n f(i)$$

    那么我们构造两个积性函数:$$h=g imes f$$

    展开:$$h(n)=sumlimits_{d|n} g(d) imes f(frac{n}{d})$$

    两边都求和:$$sumlimits_{i=1}^n h(i)=sumlimits_{i=1}^n sumlimits_{d|i} g(d) imes f(frac{i}{d})$$

    套路的换枚举项:$$sumlimits_{i=1}^n h(i)=sumlimits_{i=1}^n sumlimits_{d=1}^n [d|i] g(d) imes f(frac{i}{d})$$

    (d)([d|i])消除:$$sumlimits_{i=1}^n h(i)=sumlimits_{d=1}^n sumlimits_{i=1}^{leftlfloor frac{n}{d} ight floor} g(d) imes f(i)$$

    [sumlimits_{i=1}^n h(i)=sumlimits_{d=1}^n g(d) sumlimits_{i=1}^{leftlfloor frac{n}{d} ight floor} f(i) ]

    我们把(S(n)=sumlimits_{i=1}^n f(i))带入上式:$$sumlimits_{i=1}^n h(i)=sumlimits_{d=1}^n g(d) S(leftlfloor frac{n}{d} ight floor)$$

    那么我们现在把(d=1)的提出来:$$g(1)S(n)=sumlimits_{i=1}^n h(i)-sumlimits_{d=2}^n g(d)S(leftlfloor frac{n}{d} ight floor)$$

    那么我们现在就求出用杜教筛的式子了

    我们举个例子:

    当我们要求下式的时候:$$sumlimits_{i=1}^n mu(i)$$

    我们设:$$S(n)=sumlimits_{i=1}^n mu(i)$$

    那么我们就要求(S(n))

    我们就要构造出两个积性函数(h,g),而我们也要使得(h,g)容易求出

    我们知道:$$mu imes I=epsilon$$

    那么我们就把(g=I)(h=epsilon)

    这样带入上式的话,为:$$S(n)=1-sumlimits_{d=2}^n S(leftlfloor frac{n}{d} ight floor)$$

    那么我们知道后面半部分可以用整除分块,那么我们预处理出(n^{frac{2}{3}})(S),然后记忆化求出剩余的就行(可以具体看下面代码理解)

    再举个例子

    假如要求:$$sumlimits_{i=1}^n φ(i)$$

    那么构造函数就会想到:$$φ imes I=id$$

    那么带入就会得:$$S(n)=frac{n imes (1+n)}{2}-sumlimits_{d=2}^n S(leftlfloor frac{n}{d} ight floor)$$

    下面给出上面两个例子的代码

    美滋滋的代码时间~~~

    #include<iostream>
    #include<cstdio>
    #include<tr1/unordered_map>
    #define N 5500007
    #define ll long long
    #define il inline
    #define re register
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    using namespace std;
    int T,n,cnt;
    int sum1[N],prime[N],mu[N],phi[N];
    ll sum2[N];
    bool isp[N];
    tr1::unordered_map<int,int> map_mu;
    tr1::unordered_map<int,ll> map_phi; 
    il int read()
    {
        re int x=0,f=1; re char c=getchar();
        while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
        while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
        return x*f;
    }
    il void Get(int x)
    {
    	mu[1]=phi[1]=1;
    	for(re int i=2;i<=x;++i)
    	{
    		if(!isp[i])
    		{
    			prime[++cnt]=i;
    			mu[i]=-1;
    			phi[i]=i-1;
    		}
    		for(re int j=1;j<=cnt&&(i*prime[j])<=x;++j)
    		{
    			isp[i*prime[j]]=1;
    			if(i%prime[j]==0)
    			{
    				phi[i*prime[j]]=phi[i]*prime[j];
    				break;
    			}
    			else
    			{
    				phi[i*prime[j]]=phi[i]*phi[prime[j]];
    				mu[i*prime[j]]=-mu[i];
    			}
    		}
    	}
    	for(re int i=1;i<=x;++i)
    		sum1[i]=sum1[i-1]+mu[i],sum2[i]=sum2[i-1]+phi[i];
    }
    il int Ans_mu(ll x)
    {
    	if(x<=5500000)
    		return sum1[x];
    	if(map_mu[x])
    		return map_mu[x];
    	int ans=1;
    	for(re int l=2,r;l<=x;l=r+1)
    	{
    		r=x/(x/l);
    		ans-=(r-l+1)*Ans_mu(x/l);
    	}
    	return map_mu[x]=ans;
    }
    il ll Ans_phi(ll x)
    {
    	if(x<=5500000)
    		return sum2[x];
    	if(map_phi[x])
    		return map_phi[x];
    	ll ans=(x*(1+x))/2;
    	for(re ll l=2,r;l<=x;l=r+1)
    	{
    		r=x/(x/l);
    		ans-=(r-l+1)*Ans_phi(x/l);
    	}
    	return map_phi[x]=ans;
    }
    int main()
    {
    	T=read();
    	Get(5500000);
    	while(T--)
    	{
    		n=read();
    		printf("%lld %d
    ",Ans_phi(n),Ans_mu(n));
    	}
    	return 0;
    }
    

    再拓展一个例子:

    我们要求:$$sumlimits_{i=1}^n i imes φ(i)$$

    我们设:$$S(n)=sumlimits_{i=1}^n i imes φ(i)$$

    那么我们发现不好怎么配(g,h)函数,这个时候怎么办呢,我们把(f)化为卷积形式:$$sumlimits_{d|n} (d imes φ(d))g(frac{n}{d})$$

    那么我们发现(d)有点讨厌,那就要想办法消去,我们发现如果(g)函数为(id)函数的时候,(d)可以互相约去,也就是:$$sumlimits_{d|n} n imes φ(d)$$

    发现(n)(d)无关,可以提出来:$$nsumlimits_{d|n} φ(d)$$

    而我们发现后面一部分就是(n),所以式子就是:$$n^2$$

    那么带回去之后就是:$$S(n)=sumlimits_{i=1}^n i^2 -sumlimits_{d=2}^n d imes S(leftlfloor frac{n}{d} ight floor)$$

    我们发现只要能算出平方和的话就可以求出来了

    那么平方和怎么算呢?

    [1^2+2^2+3^2+cdots +n^2 ]

    因为(n^2=n(n+1)-n),那么得到:$$1 imes 2 -1+2 imes 3-2+3 imes 4-3+cdots +n(n+1)-n$$

    移项得:$$1 imes 2+2 imes 3+3 imes 4+cdots +n(n+1)-(1+2+3+cdots +n)$$

    因为(n(n+1)=frac{n(n+1)(n+2)-(n-1)n(n+1)}{3}),所以前一部分互相消去变成:$$frac{n(n+1)(n+2)}{3}$$

    后一部分为:$$-frac{(1+n)n}{2}$$

    原式为:$$frac{n(n+1)(n+2)}{3}-frac{(1+n)n}{2}$$

    通分:$$frac{2n(n+1)(n+2)}{6}-frac{3n(1+n)}{6}$$

    [=frac{n(1+n)(2n+1)}{6} ]

    大功告成~~~


  • 相关阅读:
    轻松记账工程冲刺第一天
    课堂练习-找水王
    NABCD模型—轻松记账
    四则运算网页版
    二维数组最大子数组(结对开发)
    软件工程结对作业01
    返回一个二维整数数组中最大联通子数组的和
    学习进度条(第六周)
    整数数组中最大子数组的和
    学习进度条(第五周)
  • 原文地址:https://www.cnblogs.com/yexinqwq/p/10392167.html
Copyright © 2011-2022 走看看