Files
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

71 lines
2.6 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
// 返回1-m中与n互素的数的个数
vector<int> p;
int cal(int n, int m) {
p.clear();
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
p.push_back(i);
while (n % i == 0) n /= i;
}
}
if (n > 1) p.push_back(n); // 求n的素因子
int s = 0; // 1到m中与n不互素的数的个数
// 枚举子集,不能有空集,所以从1开始
for (int i = 1; i < 1 << p.size(); i++) { // 从1枚举到(2^素因子个数)
int cnt = 0;
int t = 1;
for (int j = 0; j < p.size(); j++) { // 枚举每个素因子
if (i & (1 << j)) { // 有第i个因子
cnt++; // 计数
t *= p[j]; // 乘上这个质因子
}
}
// 容斥原理
if (cnt & 1) // 选取个数为奇数,加
s += m / t;
else // 选取个数为偶数,减
s -= m / t;
}
return m - s; // 返回1-m中与n互素的数的个数
}
int T, ca;
signed main() {
cin >> T;
while (T--) {
int a, b, c, d, k;
cin >> a >> b >> c >> d >> k;
// k=0时需要特判,因为我们想要 x'=x/k ,y'=y/k,不能随意除,需要判断
if (k == 0) { // k=0时,表示gcd(x,y)=0
/*
如果两个数的最大公约数是0,这意味着这两个数中至少有一个数是0。
因为最大公约数是两个数共有的最大因子,而0没有最大因子,所以0
与任何数的最大公约数都是0。
而a<=x<=b,c<=y<=d,a=c=1,所以,k=0是不可能存在gcd(x,y)=0的,应该返回0对
*/
printf("Case %lld: 0\n", ++ca);
continue;
}
b /= k, d /= k;
// 因为 (1,3)与 (3,1)算1个,所以要限制x<y
// a=c=1
if (b > d) swap(d, b);
int ans = 0;
// d>b
for (int i = 1; i <= d; i++) // 枚举大区间
// c(n,m): 返回1-m中与n互素的数的个数
// 拿大区间[1~d]中的每个数字i,去 [1~b]中找与其互质的数
// 但是,这样做的话,会出现 [1,3],[3,1]这样的情况,为了防止这样的事情发生
// 我们需要控制区间的范围,也就是小于等于i,同时,也要考虑i与b的大小关系,保证i<=b
// 也就是 min(i,b)
ans += cal(i, min(i, b));
printf("Case %lld: %lld\n", ++ca, ans);
}
}