洛谷P3768 简单的数学题 题解

该博客介绍了如何利用欧拉筛、莫比乌斯反演和狄利克雷卷积解决洛谷P3768题目。首先讲解了相关数学基础知识,然后通过莫反将问题转化为求解F函数,F函数可通过欧拉筛求得前缀和。由于n的范围较大,引入杜教筛优化,以O(n^1.5)的时间复杂度求解问题。最后给出了代码实现。

1.前置知识:

欧拉筛,莫比乌斯反演,狄利克雷卷积,杜教筛

2.莫反+狄利克雷卷积+欧拉筛

看到这道题的瞬间,按照DNA来一个莫反

∑i=1n∑j=1nijgcd⁡(i,j)=∑k=1nk∑i=1n∑j=1nij[gcd⁡(i,j)=k]=∑k=1nk3∑i=1⌊nk⌋∑j=1⌊nk⌋ij[gcd⁡(i,j)=1]=∑k=1nk3∑i=1⌊nk⌋∑j=1⌊nk⌋ij∑d∣gcd⁡(i,j)μ(d)=∑k=1nk3∑d=1⌊nk⌋μ(d)∑i=1⌊nk⌋∑j=1⌊nk⌋ij[d∣gcd⁡(i,j)]=∑k=1nk3∑d=1⌊nk⌋μ(d)d2∑i=1⌊nkd⌋i∑j=1⌊nkd⌋j \begin{aligned} &\sum_{i=1}^{n}\sum_{j=1}^{n}{ij\gcd(i,j)}\\ =&\sum_{k=1}^{n}k\sum_{i=1}^{n}\sum_{j=1}^{n}{ij[\gcd(i,j)=k]}\\ =&\sum_{k=1}^{n}{k^3}\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{k}\rfloor}{ij[\gcd(i,j)=1]}\\ =&\sum_{k=1}^{n}{k^3}\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{k}\rfloor}{ij\sum_{d|\gcd(i,j)}{\mu(d)}}\\ =&\sum_{k=1}^{n}{k^3}\sum_{d=1}^{\lfloor\frac{n}{k}\rfloor}{\mu(d)}\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{k}\rfloor}{ij[d|\gcd(i,j)]}\\ =&\sum_{k=1}^{n}{k^3}\sum_{d=1}^{\lfloor\frac{n}{k}\rfloor}{\mu(d)d^2}\sum_{i=1}^{\lfloor\frac{n}{kd}\rfloor}i\sum_{j=1}^{\lfloor\frac{n}{kd}\rfloor}{j}\\ \end{aligned} =====i=1nj=1nijgcd(i,j)k=1nki=1nj=1nij[gcd(i,j)=k]k=1nk3i=1knj=1knij[gcd(i,j)=1]k=1nk3i=1knj=1knijdgcd(i,j)μ(d)k=1nk3d=1knμ(d)i=1knj=1knij[dgcd(i,j)]k=1nk3d=1knμ(d)d2i=1kdnij=1kdnj

根据莫反惯例,设T=kd,sum(x)=∑i=1niT=kd,sum(x)=\sum_{i=1}^{n}iT=kd,sum(x)=i=1ni

则原式可化为:

∑T=1nsum(⌊nT⌋)2∑d∣Td2μ(d)(Td)3=∑T=1nsum(⌊nT⌋)2T2∑d∣Tμ(d)(Td) \begin{aligned} &\sum_{T=1}^{n}sum(\lfloor\frac{n}{T}\rfloor)^2\sum_{d|T}{d^2\mu(d)(\frac{T}{d})^3}\\ =&\sum_{T=1}^{n}sum(\lfloor\frac{n}{T}\rfloor)^2T^2\sum_{d|T}{\mu(d)(\frac{T}{d})}\\ \end{aligned} =T=1nsum(Tn)2dTd2μ(d)(dT)3T=1nsum(Tn)2T2dTμ(d)(dT)


F(T)=T2∑d∣Tμ(d)(Td)F(T)=T^2\sum_{d|T}{\mu(d)(\frac{T}{d})}F(T)=T2dTμ(d)(dT)

根据狄利克雷卷积可知,

F(T)=T2∑d∣Tμ(d)(Td)=T2∗((id×μ)(T))=T2∗((I×φ×μ)(T))=T2∗((I×μ×φ)(T))=T2∗((I×μ×φ)(T))=T2∗((ϵ×φ)(T))=T2φ(T) \begin{aligned} F(T)&=T^2\sum_{d|T}{\mu(d)(\frac{T}{d})}\\ &=T^2*((id\times\mu)(T))\\ &=T^2*((I\times\varphi\times\mu)(T))\\ &=T^2*((I\times\mu\times\varphi)(T))\\ &=T^2*((I\times\mu\times\varphi)(T))\\ &=T^2*((\epsilon\times\varphi)(T))\\ &=T^2 \varphi(T)\\ \end{aligned} F(T)=T2dTμ(d)(dT)=T2((id×μ)(T))=T2((I×φ×μ)(T))=T2((I×μ×φ)(T))=T2((I×μ×φ)(T))=T2((ϵ×φ)(T))=T2φ(T)

原式可以化成

∑T=1nsum(⌊nT⌋)2F(T)\sum_{T=1}^{n}sum(\lfloor\frac{n}{T}\rfloor)^2F(T)T=1nsum(Tn)2F(T)

F函数可以用欧拉筛线性求出,求出F的前缀和后式子可以在O(n)O(\sqrt{n})O(n)的复杂度内求出

现在,这道题可以做到O(n)O(n)O(n)求解,能拿60分。

3.杜教筛优化

但是,n的范围达到了1e10,因此我们必须通过比欧拉筛的方式求出F的前缀和,比如说杜教筛


S(n)=∑i=1nf(i)S(n)=\sum_{i=1}^nf(i) S(n)=i=1nf(i)
g(n)=n2g(n)=n^2 g(n)=n2
h(n)=(f×g)(n)=∑d∣nd2φ(d)(nd)2=n2∗∑d∣nφ(d)=n3h(n)=(f\times g)(n)=\sum_{d|n}{d^2\varphi(d)(\frac{n}{d})^2} =n^2*\sum_{d|n}\varphi(d)=n^3 h(n)=(f×g)(n)=dnd2φ(d)(dn)2=n2dnφ(d)=n3
sump(n)=∑i=1ni2sump(n)=\sum_{i=1}^ni^2sump(n)=i=1ni2

由伟大的杜教筛式子得:

S(n)g(1)=∑i=1nh(i)−∑i=2nS(⌊ni⌋)g(i)S(n)g(1)=\sum_{i=1}^nh(i)-\sum_{i=2}^nS(\lfloor \frac{n}{i}\rfloor)g(i) S(n)g(1)=i=1nh(i)i=2nS(in)g(i)

代入定义可得

S(n)=∑i=1ni3−∑i=2ni2S(⌊ni⌋)S(n)=\sum_{i=1}^ni^3-\sum_{i=2}^ni^2S(\lfloor \frac{n}{i}\rfloor)S(n)=i=1ni3i=2ni2S(in)

由一个小学奥数和两个定积分得:

sum(n)=n(n+1)2sum(n)=\frac{n(n+1)}{2}sum(n)=2n(n+1)
sump(n)=n2(n+1)24sump(n)=\frac{n^2(n+1)^2}{4}sump(n)=4n2(n+1)2
∑i=1ni3=sum(n)2\sum_{i=1}^ni^3=sum(n)^2i=1ni3=sum(n)2

那么我们现在可以用杜教筛求出S(n)了。

杜教筛的时间复杂度为O(n23)O(n^\frac{2}{3})O(n32),属于O(能过)的范围内。

4.代码


#include<bits/stdc++.h>
using namespace std;
#define LL long long 
#define maxn 5000005
bool vis[maxn];
int cnt,prime[maxn],phi[maxn];
LL s1[maxn],n,mod,inv6,inv2;
map <LL,LL> s2;
LL sum(LL x)
{
    x%=mod;
  return x*(1+x)%mod*inv2%mod;
}

LL sump(LL x)
{
    x%=mod;
  return x*(1+x)%mod*(1+x+x)%mod*inv6%mod;
}
void oula(LL n)
{
  phi[1]=1;
  for(int i=2;i<=n;i++)
  {
    if(!vis[i])
    {
      prime[++cnt]=i;
      phi[i]=i-1;
    }
    for(int j=1;j<=cnt&&i*prime[j]<=n;j++)
    {
      vis[i*prime[j]]=1;
      if(i%prime[j])
      {
        phi[i*prime[j]]=phi[i]*(prime[j]-1);
      }else
      {
        phi[i*prime[j]]=phi[i]*prime[j];
      }
    }
  }
  for(int i=1;i<=n;i++)
  {
    s1[i]=s1[i-1]+1ll*i*i%mod*phi[i]%mod;
    s1[i]%=mod;
  }
}
LL dujiao(LL n)
{
  if(n<=maxn-5)return s1[n];
  if(s2[n])return s2[n];
  LL ret = sum(n);
  ret=ret*ret%mod;
  for(LL l=2,r=0;l<=n;l=r+1)
  {
    r=n/(n/l);
    LL tt=(sump(r)-sump(l-1))%mod;
    ret-=tt*dujiao(n/l)%mod;
    ret%=mod;
  }
  ret=(ret+mod)%mod;
  s2[n]=ret;
  return ret;
}
LL solve(LL n)
{
  LL ret=0;
  for(LL l=1,r=0;l<=n;l=r+1)
  {
    r=(n/(n/l));
    LL tt=sum(n/l);tt=tt*tt%mod;
    LL gg=dujiao(r)-dujiao(l-1);gg%=mod;
    ret+=gg*tt%mod;
    ret%=mod;
  }
  ret=(ret+mod)%mod;
  return ret;
}

LL fpow(LL a,LL b)
{
    LL s=1;
    while(b){if(b&1)s=s*a%mod;a=a*a%mod;b>>=1;}
    return s;
}
int main()
{
  scanf("%lld%lld",&mod,&n);
  inv2=fpow(2,mod-2);
  inv6=fpow(6,mod-2);
  oula(maxn-5);
  printf("%lld",solve(n));
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值