模板 - 莫比乌斯反演
Posted yinku
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板 - 莫比乌斯反演相关的知识,希望对你有一定的参考价值。
P3455 [POI2007]ZAP-Queries https://www.luogu.org/problemnew/show/P3455
最简单的求gcd==d的个数,直接分块瞎搞。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 50000
int mu[MAXN+5];
int pri[MAXN+5],pritop;
bool notpri[MAXN+5];
//pritop从1开始计数
int summu[MAXN+5];
void sieve3(int n) {
notpri[1]=mu[1]=1;
for(int i=2; i<=n; i++) {
if(!notpri[i])
pri[++pritop]=i,mu[i]=-1;
for(int j=1; j<=pritop&&i*pri[j]<=n; j++) {
notpri[i*pri[j]]=1;
//略有不同
if(i%pri[j])
mu[i*pri[j]]=-mu[i];
else {
mu[i*pri[j]]=0;
break;
}
}
}
for(int i=1;i<=n;i++){
summu[i]=summu[i-1]+mu[i];
}
}
//整除分块,n,m版
ll aliquot_patition(ll n,ll m,ll d) {
ll ans=0;
int N=min(n,m);
for(ll l=1,r; l<=N; l=r+1) {
r=min(n/(n/l),m/(m/l));
ans+=1ll*(n/(l*d))*(m/(l*d))*(summu[r]-summu[l-1]);
}
return ans;
}
int main() {
sieve3(MAXN);
int t;
scanf("%d",&t);
int n,m,d;
while(~scanf("%d%d%d",&n,&m,&d)){
printf("%lld
",aliquot_patition(n,m,d));
}
}
https://www.luogu.org/problemnew/show/P2522
没事别用 long long ,常数卡死你!
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 50000
int mu[MAXN+5];
int pri[MAXN+5],pritop;
bool notpri[MAXN+5];
//pritop从1开始计数
int summu[MAXN+5];
void sieve3(int n) {
notpri[1]=mu[1]=1;
for(int i=2; i<=n; i++) {
if(!notpri[i])
pri[++pritop]=i,mu[i]=-1;
for(int j=1; j<=pritop&&i*pri[j]<=n; j++) {
notpri[i*pri[j]]=1;
//略有不同
if(i%pri[j])
mu[i*pri[j]]=-mu[i];
else {
mu[i*pri[j]]=0;
break;
}
}
}
for(int i=1;i<=n;i++){
summu[i]=summu[i-1]+mu[i];
}
}
//整除分块,n,m版
int aliquot_patition(int n,int m,int d) {
int ans=0;
int N=min(n,m);
for(int l=1,r; l<=N; l=r+1) {
r=min(n/(n/l),m/(m/l));
ans+=1ll*(n/(l*d))*(m/(l*d))*(summu[r]-summu[l-1]);
}
return ans;
}
int solve(int a,int b,int c,int d,int k){
int sum1=aliquot_patition(b,d,k);
int sum2=aliquot_patition(a-1,d,k);
int sum3=aliquot_patition(b,c-1,k);
int sum4=aliquot_patition(a-1,c-1,k);
return sum1+sum4-sum2-sum3;
}
int main() {
sieve3(MAXN);
int t;
scanf("%d",&t);
int a,b,c,d,k;
while(~scanf("%d%d%d%d%d",&a,&b,&c,&d,&k)){
printf("%d
",solve(a,b,c,d,k));
}
}
以上是关于模板 - 莫比乌斯反演的主要内容,如果未能解决你的问题,请参考以下文章