莫比乌斯反演题目

持续更新ing

唔。从年前就想要搞,但是一直鸽到现在。

不过,就从现在开始吧!!!

前导知识

莫比乌斯反演定理两种形式的证明

目录

1.luogoP2568 GCD

2.luoguP2257 YY的GCD

 

1.luogoP2568 GCD 

题目链接

莫比乌斯反演的入门题。

思路:

ans=\sum _{i=1}^{n}\sum _{j=1}^{n}[gcd(i,j)=prim]=\sum _{d=1}^{n}[d=prim] \sum _{i=1}^{\frac{n}{d}}\sum _{j=1}^{\frac{n}{d}}[gcd(i,j)=1]

g\left ( n \right )=\sum _{i=1}^{n}\sum _{j=1}^{n}[gcd(i,j)=1]= \sum _{i=1}^{n}\sum _{j=1}^{n}\sum _{d|gcd(i,j)}u\left ( d \right )= \sum _{d=1}^{n}\left ( \frac{n}{d} \right )^2u(d)

ans=\sum _{d=1}^{n}[d=prim]g\left ( \frac{n}{d} \right )

代码:

#include
#include
#include
using namespace std;
const int N=1e7+100;
int n;
long long ans;
int vis[N],u[N],sum[N];
int p[N];
int cnt=0;
void seive(){
	vis[0]=1;
	vis[1]=1;
	u[1]=1;
	for(int i=2;i<=n;++i){
		if(!vis[i])p[cnt++]=i,u[i]=-1;
		for(int j=0;j

2.luoguP2257 YY的GCD

题目链接

思路:

设    f\left ( n \right )=\sum _{n|d}[gcd\left ( i,j \right )=n]  ,F\left ( n \right )=\sum _{n|d}f\left ( d \right )=\frac{N}{n}*\frac{M}{n}

ans=\sum _{i=1}^{N}\sum _{j=1}^{M}[gcd(i,j)\in \mathbb{P}]=\sum _{n=1,n\in \mathbb{P}}^{min\left ( N,M \right )} \sum _{i=1}^{N}\sum _{j=1}^{M}[gcd(i,j)=n]=\sum _{n=1,n\in \mathbb{P}}^{min\left ( N,M \right )}f\left ( n \right )

根据莫比乌斯反演定理F\left ( n \right )=\sum _{n|d}f\left ( d \right )     =>     f\left ( n \right )=\sum _{n|d}u\left ( \frac{d}{n} \right )F\left ( d \right ) 得,

ans=\sum _{n=1,n\in \mathbb{P}}^{min\left ( N,M \right )}\sum _{n|d}u\left ( \frac{d}{n} \right )F\left ( d \right )=\sum _{n=1,n\in \mathbb{P}}^{min\left ( N,M \right )}\sum _{n|d}u\left ( \frac{d}{n} \right )\frac{N}{d}\frac{M}{d}

=\sum_{d=1}^{N}\frac{N}{d}\frac{M}{d}\sum _{n|d,n\in \mathbb{P}}u\left ( \frac{d}{n} \right )

g\left ( d \right )=\sum _{n|d,n\in \mathbb{P}}u\left ( \frac{d}{n} \right )

筛的时候先O\left ( n \right )筛出来u\left ( n \right ),再求g\left ( n \right ),求g\left ( n \right )得时候时间复杂度跟埃氏筛差不多。再对g\left ( n \right )求前缀和。

然后就是整除分块的套路写法了。

代码:

#include
#include
using namespace std;
const int N=1e7+100;
int vis[N],u[N],p[N];
long long g[N],sum[N],ans;
int cnt,t,n,m;
void seive(){
	vis[1]=1;
	u[1]=1;
	for(int i=2;im)n^=m^=n^=m;
		ans=cal(n,m);
		printf("%lld\n",ans);
	}
	return 0;
} 

 

你可能感兴趣的:(◈数论,▫▫▫▫▫莫比乌斯反演)