关于Mobius反演

数论函数

定义域为整数,值域为复数的函数

积性函数:若 ,则

除数函数


除数函数为积性函数。

欧拉函数

表示不超过 且与 互质的正整数的个数

其中 的标准分解。
由此易见 函数是积性函数。
同时满足

线性求 函数:

#define int long long
int phi[3000005];
int n=3000000;
bool mark[3000005];
int prime[1000005];
int tot;
void getphi()
{
    phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(mark[i]==false)
        {
            prime[++tot]=i;
            phi[i]=i-1;
        }
        for(int j=1;j<=tot;j++)
        {
            if(i*prime[j]>n)
            {
                break;
            }
            mark[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            phi[i*prime[j]]=phi[i]*phi[prime[j]];
        }
    }
    for(int i=1;i<=n;i++)
    {
        phi[i]+=phi[i-1];
    }
}

函数

证明:
$$

其中

那么

根据二项式定理,易知该式子的值在 时值为 否则为 ,这也同时证明了

#define int long long
int mu[3000005];
int n=3000000;
bool mark[3000005];
int prime[1000005];
int tot;
void getmu()
{
    mu[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(mark[i]==false)
        {
            prime[++tot]=i;
            mu[i]=-1;
        }
        for(int j=1;j<=tot;j++)
        {
            if(i*prime[j]>n)
            {
                break;
            }
            mark[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                mu[i*prime[j]]=0;
                break;
            }
            mu[i*prime[j]]=-mu[i];
        }
    }
}

卷积



定义两个数论函数的卷积为:
$\text{Dirichlet}\varepsilon\varepsilon(n)=[n==1]\varepsilon1*\mu=\varepsilon\mu * \text{ID} = \varphi1*\text{ID}=\sigma$

莫比乌斯反演

公式:设 为两个数论函数。
如果有
$f=g*1g=f*\muf\mu=g1\mu= g\varepsilon=g1*\mu=\varepsilon$ )

同时,还有另一种反演:
如果有
$$

整除分块

当遇到形如
$O(\sqrt {n})i\frac{n}{i}\frac{n}{i}xx\frac{n}{x}$。

  • 证明:反证法:对于数,它所在的块的值为,且和数不在同一个块中。
    然后,原命题得证。

所以,易得计算原式方法。

for(int l=1,r;l<=n;l=r+1)
{
    r=n/(n/l);
    ans+=(r-l+1)*(n/l);
}

P2257 YY的GCD


由莫比乌斯反演:





改为枚举




代码:
//sum即为的前缀和

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int prime[10000005];
int mu[10000005];
ll f[10000005];
ll sum[10000005];
bool vis[10000005];
int cnt;
void init()
{
    mu[1]=1;
    for(int i=2;i<=10000000;i++)
    {
        if(vis[i]==false)
        {
            mu[i]=-1;
            prime[++cnt]=i;
        }
        for(int j=1;j<=cnt&&i*prime[j]<=10000000;j++)
        {
            vis[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                break;
            }
            mu[i*prime[j]]=-mu[i];
        }
    }
    for(int i=1;i<=cnt;i++)
    {
        for(int j=1;j*prime[i]<=10000000;j++)
        {
            f[j*prime[i]]+=mu[j];
        }
    }
    for(int i=1;i<=10000000;i++)
    {
        sum[i]=sum[i-1]+f[i];
    }
}
ll solve(int a,int b)//运用整除分块
{
    ll ans=0;
    if(a>b)
    {
        swap(a,b);
    }
    for(int l=1,r=0;l<=a;l=r+1)
    {
        r=min(a/(a/l),b/(b/l));
        ans+=(ll)(sum[r]-sum[l-1])*(a/l)*(b/l);
    }
    return ans;
}
signed main()
{
    init();
    int T;
    cin>>T;
    for(int i=1;i<=T;i++)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        printf("%lld\n",solve(a,b));
    }
    return 0;
}

常用柿子


$$

调和数



杜教筛

快速求出
由于
可得


右边为子问题,可以递归解决,再加整除分块,可以保证每个点被计算一遍
复杂度

代码:

#include<bits/stdc++.h>
using namespace std;
#define re register
#define ll long long
#define N 5500000
ll phi[N+5];
int mu[N+5];
int prim[N+5];
bool mark[N+5];
int cnt;
unordered_map<int,ll> aphi;
unordered_map<int,int> amu;
void init()
{
    phi[1]=1;
    mu[1]=1;
    for(re int i=2;i<=N;i++)
    {
        if(mark[i]==false)
        {
            phi[i]=i-1;
            mu[i]=-1;
            prim[++cnt]=i;
        }
        for(re int j=1;j<=cnt;j++)
        {
            if(i*prim[j]>N)
            {
                break;
            }
            mark[i*prim[j]]=true;
            if(i%prim[j]==0)
            {
                phi[i*prim[j]]=phi[i]*prim[j];
                mu[i*prim[j]]=0;
                break;
            }
            phi[i*prim[j]]=phi[i]*phi[prim[j]];
            mu[i*prim[j]]=-mu[i];
        }
    }
    for(re int i=1;i<=N;i++)
    {
        phi[i]+=phi[i-1];
        mu[i]+=mu[i-1];
    }
}
ll getphi(int x)
{
    if(x<=N)
    {
        return phi[x];
    }
    if(aphi[x]!=0)
    {
        return aphi[x];
    }
    ll ans=(ll)x*(x+1)/2;
    for(int l=2,r=0;r!=2147483647&&l<=x;l=r+1)
    {
        r=x/(x/l);
        ans-=(ll)(r-l+1)*getphi(x/l);
    }
    return aphi[x]=ans;
}
int getmu(int x)
{
    if(x<=N)
    {
        return mu[x];
    }
    if(amu[x]!=0)
    {
        return amu[x];
    }
    int ans=1;
    for(int l=2,r=0;r!=2147483647&&l<=x;l=r+1)
    {
        r=x/(x/l);
        ans-=(r-l+1)*getmu(x/l);
    }
    return amu[x]=ans;
}
int main()
{
    init();
    int T;
    cin>>T;
    int x;
    for(int i=1;i<=T;i++)
    {
        scanf("%d",&x);
        printf("%lld %d\n",getphi(x),getmu(x));
    }
    return 0;
}
全部评论

相关推荐

09-24 20:07
门头沟学院 Java
点赞 评论 收藏
分享
如题,8.13一面,8.16二面,8.29三面,9.3四面,9.19HR面,9.23流程结束技术面完就该确定要不要人了吧,还非要加个HR面然后再综合排序,纯浪费我时间
勤奋努力的大熊猫已转码:这也太逆天了,我记得每家公司在招聘开始的时候,都会给面试官一个准则:应聘者即使最后没有获得职位,其对公司的认可度也应当提高,显然大部分公司都做不到这一点
点赞 评论 收藏
分享
zxxxxxr:不是挂了,是美团招聘特有机制,三天第一志愿没处理会自动结束跳转到第二志愿,以此类推,只要有人后面捞也会回到第一志愿的
投递美团等公司10个岗位
点赞 评论 收藏
分享
bg:弱211本&nbsp;26届日常实习大二下的时候开始找了第一段实习,找的比较随意,随便找了个小厂🐶了三个月(4月到6月),最后以回学校准备期末考告终,开发流程不是特别规范,但是感觉那段时间是自己成长最快的阶段。7月份报名了移动的线上实习,做的是效益评估智慧管理平台,技术难点主要是业务实现,没什么并发难度,所以就抱着边写代码边啃算法和小林的计划,自己在图书馆学习了。此外,自己还有一段开源经历,研究的是JDK协程在completeableFuture下的自旋优化。自八月底,开始海投简历,项目用马哥的牛券和短链接。百度快手bilibili(简历挂)腾讯(二面挂)小红书(二面挂,现在又被一个鸡架平台捞起来了,看看有没有机会)美团(没人回,后面发现官网挺多,Boss上面岗位不多,手痒痒但还是之后再说吧)字节(一面挂了一次,又被捞,第二次二面挂,暂时不投了,心累)京东(简历挂,师姐推不过去啊)momenta(一面过了,二面结束后聊了聊感觉用cpp和py用的比较多,主动终止了)货拉拉(流程很快,一面二面就隔了一天,很快出offer,打算接)虎牙(等待一面ing,如果能拿到offer,打算看看业务怎么样,考虑)电信亿迅(oc,拒绝)360(oc,base地北京,太远了,已拒)用图科技(oc,已拒)光魔科技(oc,已拒)用友网络(oc,已拒)爱奇艺(一面后没有消息了)集度汽车(oc,已拒)开元维度(oc,已拒)moka(oc,已拒)元行科技(oc,已拒)汉朔科技(oc,已拒)。。。还有好多好多,就不一一列举了全都是在Boss上面投的,发现上面岗位不多,感觉后面还是去官网看看吧。权衡了别的offer,想到大三上学校可能还会有一些事(虽然打算全把课翘了),还有不想谈异地恋,最后还是选择base地离广州近一点的深圳。货拉拉的业务也比较感兴趣,已经约好27号入职,干到11月,满打满算简历上写3个月,沉淀一下这段实习再找下一段大厂日常实习了。个人感受:感觉现在八股问的不是特别多,很多喜欢对着实习经历和项目来问,好几场都是全程几乎没八股,都是实习、项目和场景题。或者是从简历的实习经历开始发散问一些八股,可能死磕八股现在不太行了。或者感觉,也不需要硬记八股,多看一些专栏,把那些JUC,JVM的知识点在不同的地方多见几次,可能就真的能熟悉,面试的时候按着自己的想法说出来了吧。力扣自己一直也在刷,来来回回刷了300来题,现在不少小厂都开始问算法了,难顶,看来还是继续刷。大家也一起好好加油!!!
只会一面挂:大佬tql
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务