Problem Description
Let's denote d(n) as the number of divisors of a positive integer n. You are given three integers a, b and c. Your task is to calculate the following sum:
Find the sum modulo 1073741824 (230).
Input
The first line contains three space-separated integers a, b and c (1 ≤ a, b, c ≤ 2000).
Output
Print a single integer — the required sum modulo 1073741824 (230).
Examples
Input
2 2 2
Output
20
Input
4 4 4
Output
328
Input
10 10 10
Output
11536
Note
For the first example.
- d(1·1·1) = d(1) = 1;
- d(1·1·2) = d(2) = 2;
- d(1·2·1) = d(2) = 2;
- d(1·2·2) = d(4) = 3;
- d(2·1·1) = d(2) = 2;
- d(2·1·2) = d(4) = 3;
- d(2·2·1) = d(4) = 3;
- d(2·2·2) = d(8) = 4.
So the result is 1 + 2 + 2 + 3 + 2 + 3 + 3 + 4 = 20.
题意:定义 d(n) 为 n 的除数,现在给出 a、b、c,求
思路:莫比乌斯反演
约数个数函数有一个结论:
那么推广到三个数,有:
那么,将 d(nmt) 代入 有:
化简得:
利用反演公式:
有:
化简得:
令 i=d[i],j=d[j],有:
设
则有:
求 f(n) 的时间复杂度为 O(n),那么整体复杂度为 O(n*n*logn),需要优化常数,由于 a、b、c 的顺序无影响,因此可选两个小的进行枚举,将 GCD 预处理进行记忆化
Source Program
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
const int MOD = 1073741824;
const int N = 2000+5;
const int dx[] = {-1,1,0,0,-1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;
int mu[N];
int prime[N];
bool bprime[N];
void getMu(int n){//线性筛求莫比乌斯函数
mu[1]=1;//根据定义,μ(1)=1
int cnt=0;
memset(bprime,false,sizeof(bprime));
for(int i=2;i<=n;i++){//求2~n的莫比乌斯函数
if(!bprime[i]){
prime[cnt++]=i;//存储质数
mu[i]=-1;//i为质数时,μ(1)=-1
}
for(int j=0;j<cnt;j++){//枚举i之前的素数个数
int k=i*prime[j];//素数的乘积
if(k>n)//剪枝
break;
bprime[k]=true;//不是质数
if(i%prime[j])//i不是prime[j]的整数倍时,i*prime[j]就不会包含相同质因子
mu[k]=-mu[i];//mu[k]=mu[i]*mu[prime[j]],因为prime[j]是质数,mu值为-1
else{
mu[k]=0;
break;//留到后面再筛
}
}
}
}
int a,b,c;
int table[N][N];
void minSort(){
if(a>b)
swap(a,b);
if(b>c)
swap(b,c);
if(a>b)
swap(a,b);
}
int GCD(int x,int y){
return y?GCD(y,x%y):x;
}
int F(int n,int m){
int res=0;
for(int i=1;i<=n;i++)
if(table[i][m]==1)
res+=n/i;
return res;
}
int main(){
getMu(2000);
scanf("%d%d%d",&a,&b,&c);
minSort();//使得abc变为升序
for(int i=1;i<=c;i++){//选最大c的打表
for(int j=i;j<=c;j++){
table[i][j]=GCD(i,j);
table[j][i]=GCD(i,j);
}
}
int res=0;
for(int i=1;i<=a;i++)
for(int j=1;j<=min(b,c);j++)
if(table[i][j]==1)
res+=mu[j]*(a/i)*F(b/j,i)*F(c/j,i);
res=(res%MOD+MOD)%MOD;
printf("%d\n",res);
return 0;
}