P3768 簡單的數學題(杜教篩+莫比烏斯反演)

題意

給定n和p(p爲質數)求i=1nj=1nijgcd(i,j)%p\sum_{i=1}^n\sum_{j=1}^nijgcd(i,j)\% p
n1010,5×108p1.1×109n\le 10^{10},5\times 10^8\le p\le1.1 \times 10^9

思路

經典的先提出gcd
=d=1ndi=1nj=1nij[gcd(i,j)==d]=\sum_{d=1}^nd\sum_{i=1}^n\sum_{j=1}^nij[gcd(i,j)==d]
後面的部分除以d,有
=d=1ndi=1ndj=1nddi dj[gcd(i,j)==1]=\sum_{d=1}^nd\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{n}{d}}di\ dj[gcd(i,j)==1]
提出後面的d
=d=1nd3i=1ndj=1ndij[gcd(i,j)==1]=\sum_{d=1}^nd^3\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{n}{d}}ij[gcd(i,j)==1]
然後進行莫比烏斯反演,將dnμ(d)=[n==1]\sum_{d|n}\mu(d)=[n==1]帶入有
=d=1nd3i=1ndj=1ndijkgcd(i,j)μ(k)=\sum_{d=1}^nd^3\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{n}{d}}ij\sum_{k|gcd(i,j)}\mu(k)
將k提出有,及枚舉1到nd\frac{n}{d}內k的倍數
=d=1nd3k=1ndμ(k)i=1ndkj=1ndkki kj=\sum_{d=1}^nd^3\sum_{k=1}^{\frac{n}{d}}\mu(k)\sum_{i=1}^{\frac{n}{dk}}\sum_{j=1}^{\frac{n}{dk}}ki\ kj
=d=1nd3k=1ndμ(k)k2i=1ndkj=1ndkij=\sum_{d=1}^nd^3\sum_{k=1}^{\frac{n}{d}}\mu(k)k^2\sum_{i=1}^{\frac{n}{dk}}\sum_{j=1}^{\frac{n}{dk}}ij
上式等價於
=d=1nd3dk=1nμ(k)k2i=1ndkj=1ndkij=\sum_{d=1}^nd^3\sum_{dk=1}^{n}\mu(k)k^2\sum_{i=1}^{\frac{n}{dk}}\sum_{j=1}^{\frac{n}{dk}}ij
T=dkT=dk

=d=1nd3T=1n[T%d==0]μ(Td)(Td)2i=1nTj=1nTij=\sum_{d=1}^nd^3\sum_{T=1}^{n}[T\% d==0]\mu(\frac{T}{d})(\frac{T}{d})^2\sum_{i=1}^{\frac{n}{T}}\sum_{j=1}^{\frac{n}{T}}ij
我們將d3d^3乘入
=d=1nT=1n[T%d==0]μ(Td)dT2i=1nTj=1nTij=\sum_{d=1}^n\sum_{T=1}^{n}[T\% d==0]\mu(\frac{T}{d})dT^2\sum_{i=1}^{\frac{n}{T}}\sum_{j=1}^{\frac{n}{T}}ij
這裏可以看作枚舉的是1到n中每一個d的倍數,那麼我們也等價於枚舉1到n中每個數T的因子

=T=1nT2dTdμ(Td)i=1nTj=1nTij=\sum_{T=1}^nT^2\sum_{d|T}d\mu(\frac{T}{d})\sum_{i=1}^{\frac{n}{T}}\sum_{j=1}^{\frac{n}{T}}ij
對於式子i=1nTj=1nTij\sum_{i=1}^{\frac{n}{T}}\sum_{j=1}^{\frac{n}{T}}ij

i=1nTij=1nTj=i=1nTi((nT+1)nT2)=((nT+1)nT2)2\sum_{i=1}^{\frac{n}{T}}i\sum_{j=1}^{\frac{n}{T}}j=\sum_{i=1}^{\frac{n}{T}}i(\frac{(\left \lfloor \frac{n}{T}\right \rfloor+1)\left \lfloor\frac{n}{T}\right \rfloor}{2})=(\frac{(\left \lfloor \frac{n}{T}\right \rfloor+1)\left \lfloor\frac{n}{T}\right \rfloor}{2})^2
對於式子dTdμ(Td)\sum_{d|T}d\mu(\frac{T}{d})可以發現是ididμ\mu的狄利克雷卷積idμ=φid*\mu=\varphi
所以有
=T=1nT2φ(T)((nT+1)nT2)2=\sum_{T=1}^nT^2\varphi(T)(\frac{(\left \lfloor \frac{n}{T}\right \rfloor+1)\left \lfloor\frac{n}{T}\right \rfloor}{2})^2
然後可以對
T=1nT2φ(T)\sum_{T=1}^nT^2\varphi(T)用杜教篩
f(x)=x2φ(x)f(x)=x^2\varphi(x)g(x)=x2g(x)=x^2S(n)=i=1nf(i)S(n)=\sum_{i=1}^nf(i)

i=1ngf=i=1ndig(d)f(id)=i=1ndid2(id)2φ(id)\sum_{i=1}^ng*f=\sum_{i=1}^n\sum_{d|i}g(d)f(\frac{i}{d})=\sum_{i=1}^n\sum_{d|i}d^2(\frac{i}{d})^2\varphi(\frac{i}{d})
=i=1ni2diφ(id)=\sum_{i=1}^ni^2\sum_{d|i}\varphi(\frac{i}{d})
dnφ(d)=n\sum_{d|n}\varphi(d)=n,故
=i=1ni3=\sum_{i=1}^ni^3
再看i=1ndig(d)f(id)\sum_{i=1}^n\sum_{d|i}g(d)f(\frac{i}{d})
考慮枚舉每個因子的倍數
i=1ndig(d)f(id)=d=1ng(d)i=1ndf(i)=d=1ng(d)S(nd)\sum_{i=1}^n\sum_{d|i}g(d)f(\frac{i}{d})=\sum_{d=1}^ng(d)\sum_{i=1}^{\left \lfloor\frac{n}{d}\right \rfloor}f(i)=\sum_{d=1}^ng(d)S(\left \lfloor\frac{n}{d}\right \rfloor)
g(1)S(n)+d=2ng(d)S(nd)=i=1ni3g(1)S(n)+\sum_{d=2}^ng(d)S(\left \lfloor\frac{n}{d}\right \rfloor)=\sum_{i=1}^ni^3
g(x)=x2g(x)=x^2帶入移項得
S(n)=i=1ni3d=2nd2S(nd)S(n)=\sum_{i=1}^ni^3-\sum_{d=2}^nd^2S(\left \lfloor\frac{n}{d}\right \rfloor)

i=1ni3=(n(n+1)2)2,i=1ni2=n(n+1)(2n+1)6\sum_{i=1}^ni^3=(\frac{n(n+1)}{2})^2,\sum_{i=1}^ni^2=\frac{n(n+1)(2n+1)}{6}
用杜教篩就可以做了
注意n大於int,預處理時可能會爆,注意取模

#include <bits/stdc++.h>
using namespace std;
const int N=1e7+5;
int prime[N];
long long phi[N];
int vis[N];
int cnt;
long long mod;
long long inv2;
long long inv4;
long long inv6;
long long quickmod(long long a,long long b)
{
    long long ans=1;
    while(b)
    {
        if(b%2==1)
            ans=ans*a%mod;
        b=b/2;
        a=a*a%mod;
    }
    return ans;
}
void init()
{
    cnt=0;
    phi[1]=1;
    for(int i=2;i<N;i++)
    {
        if(!vis[i])
        {
            prime[cnt++]=i;
            phi[i]=i-1;
        }
        for(int j=0;j<cnt&&i*prime[j]<N;j++)
        {
            vis[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]*(prime[j]-1);
        }
    }
    for(int i=1;i<N;i++)
        phi[i]=(phi[i-1]+1ll*i*i%mod*phi[i]%mod)%mod;
}
map<long long,long long>P;
long long Sum2(long long n)
{
    return n%mod*((n+1)%mod)%mod*(2*n%mod+1)%mod*inv6%mod;
}
long long Sum(long long n)
{
    if(n<N) return phi[n];
    if(P[n]) return P[n];
    long long sum=n%mod*((n+1)%mod)%mod*(n%mod)%mod*((n+1)%mod)%mod*inv4%mod;
    for(long long i=2,last;i<=n;i=last+1)
    {
        last=n/(n/i);
        sum=(sum-(Sum2(last)-Sum2(i-1)+mod)%mod*Sum(n/i)%mod+mod)%mod;
    }
    return P[n]=sum;
}

int main()
{
    long long n;
    scanf("%lld%lld",&mod,&n);
    init();
    inv2=quickmod(2,mod-2);
    inv4=quickmod(4,mod-2);
    inv6=quickmod(6,mod-2);
    long long sum=0;
    for(long long i=1,last;i<=n;i=last+1)
    {
        last=n/(n/i);
        sum=(sum+(Sum(last)-Sum(i-1)+mod)%mod*((n/i+1)%mod)%mod*((n/i)%mod)%mod*((n/i+1)%mod)%mod*((n/i)%mod)%mod*inv4%mod)%mod;
    }
    printf("%lld\n",sum);
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章