spoj 4491 莫比乌斯反演

题意:

给出a,b,求gcd(x,y)=prime的方案数,其中:1 <= x <= a && 1 <= y <= b

限制:

1 <= a,b <= 1e7

思路:

先把问题拆成一个一个来考虑,然后问题就变成gcd(x,y)=k的方案数。

设f(k)为gcd(x,y)=k的方案数,

设F(k)为gcd(x,y)为k的倍数的方案数,显然F(k)=floor(a/k)*floor(b/k)。

由莫比乌斯反演得:

f(k)=mu[1]*F[k]+mu[2]*F[2*k]+...

所以:

ans=f(prime[1])+f(prime[2])+... ---1式

把"1式"展开后发现,对于每个F(k),和它相乘的莫比乌斯系数有:mu[i],其中i<k && k%i=0 && k/i=prime。

令cnt[k]=sigma(mu[i]),其中i<k && k%i=0 && k/i=prime。

现在要预处理出cnt[],暴力预处理会超时,所以要利用莫比乌斯函数的性质,

有三种情况:

1. cnt[k]=1 其中k为质数

2. cnt[i*prime]=-cnt[i]+mu[i] 其中i%prime!=0

3. cnt[i*prime]=mu[i] 其中i%prime=0

解释下第2点:

不妨设i由且仅由奇数个不同的prime组成,因为i%prime!=0,所以i*prime由偶数个prime组成,所以cnt[i]里面的组合都因为多了一个不同质数prime而变成了自己的相反数,然后加上mu[i]。

如:

cnt[6]=mu[2]+mu[3]

cnt[30]=cnt[6*5]=mu[10]+mu[15]+mu[6]=mu[2*5]+mu[3*5]+mu[6]=(-mu[2])+(-mu[3])+mu[6]

对于第3点:

因为i%prime==0,所以i中已经含有prime,所以i*prime里面含有两个prime,所以cnt[i]中的组合都因为多了一个相同的质数然后变成0,所以最后cnt[i]=mu[i]。

如:

cnt[6]=mu[2]+mu[3]

cnt[18]=mu[6*3]=mu[6]+mu[9]=mu[6]+mu[3*3]=mu[6]+0

最后,剩下的就只有分块的问题了。

/*spoj 4491
  题意:
  给出a,b,求gcd(x,y)=prime的方案数,其中:1 <= x <= a && 1 <= y <= b
  限制:
  1 <= a,b <= 1e7
  思路:
  先把问题拆成一个一个来考虑,然后问题就变成gcd(x,y)=k的方案数。
  设f(k)为gcd(x,y)=k的方案数,
  设F(k)为gcd(x,y)为k的倍数的方案数,显然F(k)=floor(a/k)*floor(b/k)。
  由莫比乌斯反演得:
  f(k)=mu[1]*F[k]+mu[2]*F[2*k]+...
  所以:
  ans=f(prime[1])+f(prime[2])+...	---1式

  把"1式"展开后发现,对于每个F(k),和它相乘的莫比乌斯系数有:mu[i],其中i<k && k%i=0 && k/i=prime。
  令cnt[k]=sigma(mu[i]),其中i<k && k%i=0 && k/i=prime。
  现在要预处理出cnt[],暴力预处理会超时,所以要利用莫比乌斯函数的性质,
  有三种情况:
  1. cnt[k]=1 其中k为质数
  2. cnt[i*prime]=-cnt[i]+mu[i] 其中i%prime!=0
  3. cnt[i*prime]=mu[i] 其中i%prime=0

  解释下第2点:
  不妨设i由且仅由奇数个不同的prime组成,因为i%prime!=0,所以i*prime由偶数个prime组成,所以cnt[i]里面的组合都因为多了一个不同质数prime而变成了自己的相反数,然后加上mu[i]。
  如:
  cnt[6]=mu[2]+mu[3]
  cnt[30]=cnt[6*5]=mu[10]+mu[15]+mu[6]=mu[2*5]+mu[3*5]+mu[6]=(-mu[2])+(-mu[3])+mu[6]

  对于第3点:
  因为i%prime==0,所以i中已经含有prime,所以i*prime里面含有两个prime,所以cnt[i]中的组合都因为多了一个相同的质数然后变成0,所以最后cnt[i]=mu[i]。
  如:
  cnt[6]=mu[2]+mu[3]
  cnt[18]=mu[6*3]=mu[6]+mu[9]=mu[6]+mu[3*3]=mu[6]+0

  最后,剩下的就只有分块的问题了。
 */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
using namespace std;
#define LL long long
const int N=1e7+5;
const int MOD=1000000007;
int mu[N],pri[N],pcnt;
bool vis[N];
int cnt[N];
void getMu(){
	memset(vis,0,sizeof(vis));
	mu[1]=1;
	pcnt=0;
	for(int i=2;i<N;++i){
		if(!vis[i]){
			pri[pcnt++]=i;
			mu[i]=-1;
			//cnt[i]=1;
		}
		for(int j=0;j<pcnt && i*pri[j]<N;++j){
			vis[i*pri[j]]=1;
			if(i%pri[j]){
			   mu[i*pri[j]]=-mu[i];
			   //cnt[i*pri[j]]=-cnt[i]+mu[i];
			}
			else{
				mu[i*pri[j]]=0;
				//cnt[i*pri[j]]=mu[i];
				break;
			}
		}
	}
}
LL sum[N];
//0 1 1 -1 1 -2 1 0 -1 -2
void predo(){
	for(int i=2;i<N;++i){
		if(!vis[i]) cnt[i]=1;
		for(int j=0;j<pcnt && pri[j]<=i && i*pri[j]<N;++j){
			if(i%pri[j]) cnt[i*pri[j]]=-cnt[i]+mu[i];
			else{ cnt[i*pri[j]]=mu[i]; break; }
		}
	}
	//for(int i=0;i<pcnt;++i){
	//	int lim=N/pri[i];
	//	for(int j=1;j<lim;++j){
	//		cnt[j*pri[i]]+=mu[j];
	//	}
	//}
	for(int i=1;i<=N;++i)
		sum[i]=sum[i-1]+cnt[i];
}
int main(){
	getMu();
	predo();
	int T;
	int a,b;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&a,&b);
		LL ans=0;
		for(int i=1,ls=0;i<=min(a,b);i=ls+1){
			ls=min(a/(a/i),b/(b/i));
			ans+=((LL)sum[ls]-sum[i-1])*(a/i)*(b/i);
		}
		printf("%lld\n",ans);
	}
	return 0;
}

时间: 2024-08-23 16:07:20

spoj 4491 莫比乌斯反演的相关文章

zoj 3435 spoj 7001 莫比乌斯反演

zoj 3435 题意: 给出3个数a,b,c, 定义一个立方体,这个立方体有a*b*c个点,每个点的坐标都是整数(x,y,z),求经过坐标(1,1,1)和另外任意一个点(x1,y1,z1)的不同的直线有多少条. 限制: 2 <= a,b,c <= 1e6; 有200组数据. 思路: 有3种情况: 1. x1,y1,z1都大于等于2: 问题就变成求1 <= x <= a-1 && 1 <= y <= b-1 && 1 <= z &l

SPOJ VLATTICE 莫比乌斯反演

题目链接:https://www.spoj.com/problems/VLATTICE/en/ VLATTICE - Visible Lattice Points Description Consider a NNN lattice. One corner is at (0,0,0) and the opposite one is at (N,N,N). How many lattice points are visible from corner at (0,0,0) ? A point X

bzoj 2820 / SPOJ PGCD 莫比乌斯反演

那啥bzoj2818也是一样的,突然想起来好像拿来当周赛的练习题过,用欧拉函数写掉的. 求$(i,j)=prime$对数 \begin{eqnarray*}\sum_{i=1}^{n}\sum_{j=1}^{m}[(i,j)=p]&=&\sum_{p=2}^{min(n,m)}\sum_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{p}\rfloor}[i⊥j]\newline&=&\sum_{p=

SPOJ PGCD(莫比乌斯反演)

传送门:Primes in GCD Table 题意:给定两个数和,其中,,求为质数的有多少对?其中和的范围是. 分析:这题不能枚举质数来进行莫比乌斯反演,得预处理出∑υ(n/p)(n%p==0). #pragma comment(linker,"/STACK:1024000000,1024000000") #include <cstdio> #include <cstring> #include <string> #include <cmat

SPOJ 7001(莫比乌斯反演)

传送门:Visible Lattice Points 题意:0<=x,y,z<=n,求有多少对xyz满足gcd(x,y,z)=1. 设f(d) = GCD(a,b,c) = d的种类数 : F(n) 为GCD(a,b,c) = d 的倍数的种类数, n%a == 0 n%b==0 n%c==0. 即 :F(d) = (N/d)*(N/d)*(N/d); 则f(d) = sigma( mu[n/d]*F(n), d|n ) 由于d = 1 所以f(1) = sigma( mu[n]*F(n) )

SPOJ VLATTICE Visible Lattice Points 莫比乌斯反演 难度:3

http://www.spoj.com/problems/VLATTICE/ 明显,当gcd(x,y,z)=k,k!=1时,(x,y,z)被(x/k,y/k,z/k)遮挡,所以这道题要求的是gcd(x,y,z)==1的个数+{(x,y,0)|gcd(x,y)==1}的个数+3{(0,0,1),(0,1,0),(1,0,0)} 现在不去管最后的三个坐标轴上的点, 设f(i)=|{(x,y,0)|gcd(x,y)==i}|*3+|{(x,y,z)|gcd(x,y,z)==i}|,也就是不在坐标轴上且

【BZOJ2226】[Spoj 5971] LCMSum 莫比乌斯反演(欧拉函数?)

[BZOJ2226][Spoj 5971] LCMSum Description Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes the Least Common Multiple of the integers i and n. Input The first line contains T the number of test cases. Each of the n

spoj 7001 Visible Lattice Points莫比乌斯反演

Visible Lattice Points Time Limit:7000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Description Consider a N*N*N lattice. One corner is at (0,0,0) and the opposite one is at (N,N,N). How many lattice points are visible from co

[SPOJ VLATTICE]Visible Lattice Points 数论 莫比乌斯反演

7001. Visible Lattice Points Problem code: VLATTICE Consider a N*N*N lattice. One corner is at (0,0,0) and the opposite one is at (N,N,N). How many lattice points are visible from corner at (0,0,0) ? A point X is visible from point Y iff no other lat