#P2693. 有序数对(简易版)[CF1967B1]
有序数对(简易版)[CF1967B1]
Description
[题意]给你两个正整数$n, m$,统计满足以下性质的有序数对$(a, b)$的数量。
1.$(1 \le a \le n)$,$(1 \le b \le m)$。
2.$a+b$是$b*gcd(a, b)$的倍数。
输入一个$T (1 \le T \le 10^4)$,是样例的组数。
接下来两个整数$n (1 \le n \le 2*10^6)$和$m (1 \le m \le 2*10^6)$。
在一组数据中$n$的和不超过$2*10^6$,$m$的和不超过$2*10^6$。
[样例输入]
6
1 1
2 3
3 5
10 8
100 1233
1000000 1145141
[样例输出]
1
3
4
14
153
1643498
[提示]
在第一组样例中:
有1组数对:$(1, 1)$。
在第四组样例中:
有14组数对:$(1, 1),(2, 1),(2, 2),(3, 1),(4, 1),(5, 1),(6,1 ),(6, 2),(6, 3),(7, 1),(8, 1),(9, 1),(10, 1),(10, 2)$。
Hint
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main(){
//小小数学题啦(感觉比上一题简单阿鲁!
/*
思路:
b*gcd(a, b)必然为b的倍数,那么a+b也为b的倍数。
可得a为b的倍数,gcd(a, b)为b。
考虑枚举b(i),然后每次ans加上可与当前b匹配的合法a的数量。
定义x为(a+b)/(b*gcd(a, b)),相应的每次枚举有多少个x就有多少个a。
当前b(i)中x最大取值为(n[a最大为n]+i)/(i*i)[b*gcd(a, b)],
同时x的数量也为这个最大值,直接累计和即可。
*/
int T; scanf("%d", &T);
while(T--){
LL n, m; scanf("%lld%lld", &n, &m);
LL t=sqrt(n+m), K=min(t, m), ans=0;
for(LL i=1; i<=K; i++) ans+=(n+i)/(i*i);
printf("%lld\n", ans-1);
}
return 0;
}
相关
在下列比赛中: