对于定义在非负整数上的两个函数F(x), f(x) : 若
F(n)=∑d|nf(d)
则
常见性质 :
(1)
还有一种形式的反演变换:
若 F(n)=∑n|df(d)
典型的反演:
n=∑d|nϕ(d)
ϕ(n)=∑d|nu(d)∗nd
/*莫比乌斯函数线性筛法*/
int mobius[N], prime[N];
bool vis[N];
void getMobius(){
memset(vis, 0, sizeof vis);
memset(mobius, 0, sizeof mobius);
mobius[1] = 1;
int cnt = 0;
for(int i = 2; i < N; ++i){
if(!vis[i]) {
mobius[i] = -1;/*质数**/
prime[++cnt] = i;
}
for(int j = 1; j <= cnt && i * prime[j] < N; ++j){
vis[prime[j] * i] = 1;
if(i % prime[j] == 0) {
mobius[i * prime[j]] = 0;
/**某个质因子出现两个以上*/
break;
}
mobius[i * prime[j]] = mobius[i];
}
}
}
分别在[1, n]和[1, m]中找出一对x, y满足gcd(x, y) = k
就是求在[1, n / k]和[1,m / k]中找出一对x’, y’满足gcd(x’, y’) = 1
暴力枚举极端情况O(n^2)n最大100000会T
所以定义 f(d)为[1,N]和[1,M]中gcd(x,y)=d的数对
在定义 F(x)为[1,N]和[1,M]中gcd(x,y)是d的倍数的数对
明显 F(x)=N/x∗M/x
且有公式 F(x)=∑x|df(d)
根据莫比乌斯反演, 得:
f(x)=∑x|du(dx)F(d)
因此
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int N = 100005;
int mobius[N], prime[N];
bool vis[N];
int a, b, c, d, k;
void init(){
memset(vis, 0, sizeof vis);
memset(mobius, 0, sizeof mobius);
mobius[1] = 1;
int cnt = 0;
for(int i = 2; i < N; ++i){
if(!vis[i]) {
mobius[i] = -1;
prime[++cnt] = i;
}
for(int j = 1; j <= cnt && i * prime[j] < N; ++j){
vis[prime[j] * i] = 1;
if(i % prime[j] == 0) {
mobius[i * prime[j]] = 0;
break;
}
mobius[i * prime[j]] = -mobius[i];
}
}
}
inline void input(){
cin >> a >> b >> c >> d >> k;
}
void solve(){
if(b < d) swap(b, d);
b /= k;
d /= k;
ll ans1 = 0, ans2 = 0;
for(int i = 1; i <= d; ++i){
ans1 += mobius[i] * 1ll * (b / i) * (d / i);
ans2 += mobius[i] * 1ll * (d / i) * (d / i);
}
cout << ans1 - (ans2 >> 1) << endl;
}
int main(){
int cas = 1, t;
cin >> t;
init();
while(t--){
input();
cout << "Case " << cas++ << ": ";
if(k == 0) {
cout << "0" << endl;continue;
}
solve();
}
return 0;
}