题目详情
B1. Reverse Card (Easy Version)
The two versions are different problems. You may want to read both versions. You can make hacks only if both versions are solved.
You are given two positive integers 𝑛, 𝑚.
Calculate the number of ordered pairs (𝑎,𝑏) satisfying the following conditions:
- 1≤𝑎≤𝑛, 1≤𝑏≤𝑚;
- 𝑎+𝑏 is a multiple of 𝑏⋅gcd(𝑎,𝑏).
Input
Each test contains multiple test cases. The first line contains the number of test cases 𝑡𝑡 (1≤𝑡≤10^4). The description of the test cases follows.
The first line of each test case contains two integers 𝑛, 𝑚 (1≤𝑛,𝑚≤2⋅10^6).
It is guaranteed that neither the sum of 𝑛𝑛 nor the sum of 𝑚𝑚 over all test cases exceeds 2⋅10^6.
Output
For each test case, print a single integer: the number of valid pairs.
B2. Reverse Card (Hard Version)
The two versions are different problems. You may want to read both versions. You can make hacks only if both versions are solved.
You are given two positive integers 𝑛, 𝑚.
Calculate the number of ordered pairs (𝑎,𝑏) satisfying the following conditions:
- 1≤𝑎≤𝑛, 1≤𝑏≤𝑚;
- 𝑏⋅gcd(𝑎,𝑏)is a multiple of 𝑎+𝑏.
Input
Each test contains multiple test cases. The first line contains the number of test cases 𝑡𝑡 (1≤𝑡≤10^4). The description of the test cases follows.
The first line of each test case contains two integers 𝑛𝑛, 𝑚𝑚 (1≤𝑛,𝑚≤2⋅10^6).
It is guaranteed that neither the sum of 𝑛 nor the sum of 𝑚𝑚 over all test cases exceeds 2⋅10^.
Output
For each test case, print a single integer: the number of valid pairs.
重要题干的中文翻译:
B1. Reverse Card (Easy Version)
计算满足以下条件的有序对 (𝑎,𝑏) 的数量:
1≤𝑎≤𝑛, 1≤𝑏≤𝑚;
𝑎+𝑏 是 𝑏⋅gcd(𝑎,𝑏) 的倍数。
B2. Reverse Card (Hard Version)
计算满足以下条件的有序对 (𝑎,𝑏) 的数量:
1≤𝑎≤𝑛, 1≤𝑏≤𝑚;
𝑏⋅gcd(𝑎,𝑏) 是 𝑎+𝑏 的倍数。
解题思路
对于简单版本(B1),我们需要计算满足条件 𝑎+𝑏 是 𝑏⋅gcd(𝑎,𝑏) 的倍数的有序对 (𝑎,𝑏) 的数量。这可以通过枚举所有可能的 𝑎 和 𝑏 的值,然后检查是否满足条件来完成。由于较小的约束条件 (1≤𝑛,𝑚≤2⋅10^6),这种方法是可行的。
而对于困难版本(B2),我们需要计算满足条件 𝑏⋅gcd(𝑎,𝑏) 是 𝑎+𝑏 的倍数的有序对 (𝑎,𝑏) 的数量。这个条件更加复杂,需要一种更巧妙的方法来解决。通常,这种类型的问题可能需要使用数论知识和技巧,例如分析最大公约数和最小公倍数的性质,以及利用模运算来加速计算。
B1. Reverse Card (Easy Version)
将定义为d. 假设
以及
,我们知道
.
所以我们就可以假设
,则
。因为
它们的最大公约数为1,此时
不一定总为1,所以可知在此处
。
将d从1遍历至m,我们知道,所以我们把
加入到答案中。
在这个方式下都已经包含在这个答案中,所以我们需要在ans的最后减一才是最终的答案。
时间复杂度:
B2. Reverse Card (Hard Version)
将定义为d. 假设
以及
,我们知道
.所以易知下式:
我们知道, 所以
。
, 所以
,因此
. 由此易知
。
所以(p,q)是. 我们可以遍历
,并在
的情况下计算答案。此时
的条件就满足了, 所以我们往答案里添加
时间复杂度:
代码
B1. Reverse Card (Easy Version)
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 2000005;
int tc,n,m;
ll ans;
void solve() {
cin >> n >> m;
ans = 0;
for (int i=1 ;i <= m ; i++) {
ans += (n+i)/(1ll*i*i);
}
cout<<ans-1<<'\n';
}
int main() {
cin>>tc;
while(tc--)
solve();
}
B2. Reverse Card (Hard Version)
#include <bits/stdc++.h>
using namespace std;
#define nl "\n"
#define nf endl
#define ll long long
#define pb push_back
#define _ << ' ' <<
#define INF (ll)1e18
#define mod 998244353
#define maxn 110
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
#if !ONLINE_JUDGE && !EVAL
ifstream cin("input.txt");
ofstream cout("output.txt");
#endif
int t;
cin>>t;
while(t--)
{
ll n,m; cin >> n>>m;
ll sq = sqrt(n) + 2,sqm=sqrt(m)+2;
vector bad(sq + 1, vector<bool>(sqm+1, 0));
for (ll i = 2; i <= min(sq,sqm); i++) {
for (ll a = i; a <= sq; a += i) {
for (ll b = i; b <= sqm; b += i) {
bad[a][b] = true;
}
}
}
ll ans = 0;
for (ll a = 1; a * a <= n; a++) {
for (ll b = 1; b * b <= m; b++) {
if (bad[a][b]) continue;
ans += min(n/(a+b)/a,m/(a+b)/b);
}
}
cout << ans << nl;
}
return 0;
}