莫比乌斯入门--HYSBZ - 2818
2017-08-07 13:02
274 查看
给定一个整数n,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
首先我们可以设f(d)为d=gcd(x,y)满足的对数。
设F(d)为d|gcd(x,y)满足的对数。
可知,x,y,都要能被d整除,所以有:F(d)=⌊nd⌋∗⌊nd⌋
根据莫比乌斯反演公式可知:f(x)=∑x|dμ(dx)F(d)
由于 Gcd(x,y)为素数,所以:ans=∑p∑p|dμ(dp)F(d)
所以:ans=∑d⌊nd⌋∗⌊nd⌋∗∑p|dμ(dp)
所以我们需要预处理∑p|dμ(dp),设sum(d)=∑p|dμ(dp)
由于 对任意正整数
有
μ(d
所以
当p|dp能整除d时:sum(d∗p)=μ(d)。
当p不能整除d时:sum(d∗p)=μ(d)−sum(d)
代码如下:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <bitset>
#define siz 10000005
using namespace std;
typedef long long LL;
int prime[siz],mu[siz],sum[siz];
bool check[siz];
int n;
void Mobius(){
mu[1] = 1;
prime[0] = 0;
for(int i=2;i<siz;i++){
if(!check[i]){
mu[i] = -1;
sum[i] = 1;
prime[++prime[0]] = i;
}
for(int j=1;j<=prime[0];j++){
if(i*prime[j] >= siz) break;
check[i*prime[j]] = true;
if(i%prime[j]){
mu[i*prime[j]] = -mu[i];
sum[i*prime[j]] = mu[i] - sum[i];
}
else{
mu[i*prime[j]] = 0;
sum[i*prime[j]] = mu[i];
break;
}
}
}
}
void Solve(int n)
{
LL ans = 0;
for(int i=1;i<=n;i++){
ans += 1LL*(n/i)*(n/i)*sum[i];
}
printf("%lld\n",ans);
}
int main()
{
Mobius();
scanf("%d",&n);
Solve(n);
return 0;
}
数对(x,y)有多少对.
首先我们可以设f(d)为d=gcd(x,y)满足的对数。
设F(d)为d|gcd(x,y)满足的对数。
可知,x,y,都要能被d整除,所以有:F(d)=⌊nd⌋∗⌊nd⌋
根据莫比乌斯反演公式可知:f(x)=∑x|dμ(dx)F(d)
由于 Gcd(x,y)为素数,所以:ans=∑p∑p|dμ(dp)F(d)
所以:ans=∑d⌊nd⌋∗⌊nd⌋∗∑p|dμ(dp)
所以我们需要预处理∑p|dμ(dp),设sum(d)=∑p|dμ(dp)
由于 对任意正整数
有
μ(d
所以
当p|dp能整除d时:sum(d∗p)=μ(d)。
当p不能整除d时:sum(d∗p)=μ(d)−sum(d)
代码如下:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <bitset>
#define siz 10000005
using namespace std;
typedef long long LL;
int prime[siz],mu[siz],sum[siz];
bool check[siz];
int n;
void Mobius(){
mu[1] = 1;
prime[0] = 0;
for(int i=2;i<siz;i++){
if(!check[i]){
mu[i] = -1;
sum[i] = 1;
prime[++prime[0]] = i;
}
for(int j=1;j<=prime[0];j++){
if(i*prime[j] >= siz) break;
check[i*prime[j]] = true;
if(i%prime[j]){
mu[i*prime[j]] = -mu[i];
sum[i*prime[j]] = mu[i] - sum[i];
}
else{
mu[i*prime[j]] = 0;
sum[i*prime[j]] = mu[i];
break;
}
}
}
}
void Solve(int n)
{
LL ans = 0;
for(int i=1;i<=n;i++){
ans += 1LL*(n/i)*(n/i)*sum[i];
}
printf("%lld\n",ans);
}
int main()
{
Mobius();
scanf("%d",&n);
Solve(n);
return 0;
}
相关文章推荐
- HYSBZ - 2818(gcd(n,m)为素数的对数
- HYSBZ - 2005 莫比乌斯反演
- HYSBZ 2818 (GCD)莫比乌斯反演
- HYSBZ - 2818(gcd(n,m)为素数的对数
- HYSBZ 2301 Promblem b 莫比乌斯反演+分块
- HYSBZ - 2818(gcd(n,m)为素数的对数
- HYSBZ 2038 小Z的袜子(hose) (莫队算法入门)
- HYSBZ - 2818(gcd(n,m)为素数的对数
- HYSBZ - 2818(gcd(n,m)为素数的对数
- 能量采集 HYSBZ - 2005(莫比乌斯)(详细过程推导)
- HYSBZ - 2818(gcd(n,m)为素数的对数
- HYSBZ - 2818(gcd(n,m)为素数的对数
- HYSBZ - 2818(gcd(n,m)为素数的对数
- HYSBZ - 2818(gcd(n,m)为素数的对数
- HYSBZ - 2818(gcd(n,m)为素数的对数
- HYSBZ/BZOJ 2154 Crash的数字表格 - 莫比乌斯反演
- HYSBZ - 1036 树的统计Count(树剖)
- BZOJ2818 GCD 【莫比乌斯反演】
- BZOJ 2818 Gcd (莫比乌斯反演 或 欧拉函数)
- 序列分割 HYSBZ - 3675 斜率dp