[51Nod1244]莫比乌斯函数之和

题意

  给定 l,r ,求 ri=lμ(i)

解法

  和上一题差不多,只是推的式子不一样而已
   [n=1]=d|nμ(d)···
  由①得: μ(n)=[n=1]d|n,d<nμ(d)···
  令 M(n)=ni=1μ(i) ,将②带入得到:

M(n)=i=1n[[i=1]d|i,d<iμ(d)]=1i=2nd|i,d<iμ(d)

  采用和上一题一样的套路,变化得到:
M(n)=1i=2nd=1niμ(d)=1i=2nM(ni)

  然后就可以直接杜教筛了

复杂度

O( kn23 ), k <script type="math/tex" id="MathJax-Element-1249">k</script>为常数

代码

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<map>
#define Rint register int
#define Lint long long int
using namespace std;
const int N=5000010;
bool vis[N];
int pri[N/10],miu[N],sum[N];
int cnt;
map<Lint,int> f;
void Prepare()
{
    miu[1]=1;
    for(int i=2;i<N;i++)
    {
        if( !vis[i] )   pri[++cnt]=i,miu[i]=-1;
        for(int j=1;j<=cnt;j++)
        {
            int x=pri[j]*i;
            if( x>=N )   break ;
            vis[x]=1;
            if( i%pri[j] )   miu[x]=-miu[i];
            else   break ;
        }
    }
    for(int i=1;i<N;i++)   sum[i]=sum[i-1]+miu[i];
}
int cal(Lint n)
{
    if( n<N )   return sum[n];
    if( f.count(n) )   return f[n];
    Lint x=2;int ret=1;
    while( x<=n )
    {
        Lint y=n/(n/x);
        ret-=(y-x+1)*cal(n/x),x=y+1;
    }
    return f[n]=ret;
}
int main()
{
    Lint l,r;
    Prepare();
    scanf("%lld%lld",&l,&r);
    printf("%d\n",cal(r)-cal(l-1));
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值