看了一天终于把”懵逼武士“入门了,那些大佬们都太强了。
学习moblus必须耐心看数学公式和推算证明,如果不能做到这点最好先放一放,提高一下数学思维再来学习。
需要明确的是莫比乌斯反演是一种类似“逆”的东西,正着做题不好解,但是逆向思考就很简单了。
对于莫比乌斯反演的学习网上有很多博客,但是有的讲得不是很好,我把我认为讲得很好的链接放在下面,可以方便读者更快地学习。(我的推荐有两个链接,第一个是博客,第二个是ppt,博客中有关于反演证明的详细解释,很赞。)
https://wenku.baidu.com/view/fbec9c63ba1aa8114431d9ac.html
代码:
bool check[maxn];
int prime[maxn];
int mu[maxn];
void Moblus(){
memset(check,false,sizeof(check));
mu[1] = 1;
int tot = 0;
for(int i = 2;i <= maxn;i++){
if(!check[i]){
prime[tot++] = i;
mu[i] = -1;
}
for(int j = 0;j < tot;j++){
if(i*prime[j] > maxn) break;
check[i*prime[j]] = true;
if(i % prime[j] == 0){
mu[i*prime[j]] = 0;
break;
}
else{
mu[i*prime[j]] = -mu[i];
}
}
}
}
整除分块:
int sum[maxn];
ll solve(int n,int m){
ll ans = 0;
if(n > m) swap(n,m);
for(int i = 1,last = 0;i <= n;i = last+1){
last = min(n/(n/i),m/(m/i));
ans += (ll)(sum[last]-sum[i-1])*(n/i)*(m/i);
}
return ans;
}
推荐一个讲整除分块的博客,讲得很好: