CF1967B2 思路分享(数论)
https://codeforces.com/problemset/problem/1967/B2
题意
给定 \(n,m\),求:
-
\(1\le a \le n\),\(1\le b \le m\)
-
\((a+b) \mid (b\cdot \gcd(a,b))\)
的数量.
\(1\le n,m\le 2\cdot 10^6\).
思路
求
\[\sum_{a=1}^{n}{\sum_{b=1}^{m}{[(a+b) \mid (b\cdot \gcd(a,b))]}}
\]
枚举公因数 \(d\)
\[\sum_{a=1}^{n}{\sum_{b=1}^{m}{\sum_{d\mid a,d\mid b}{[\gcd(\frac{a}{d},\frac{b}{d})=1][(a+b) \mid (b\cdot d)]}}}
\]
交换求和,换元化简
\[\sum_{d}{\sum_{a=1}^{\left\lfloor\frac{n}{d}\right\rfloor}{\sum_{b=1}^{\left\lfloor\frac{m}{d}\right\rfloor}{[\gcd(a,b)=1][(a+b)\mid (b\cdot d)]}}}
\]
因为 \(\gcd(a,b)=1\),即 \(\gcd(a+b,b)=1\),因此 \((a+b)\mid(b\cdot d)\) 等价于 \((a+b)\mid d\),因此 \(a\le d\),\(b\le d\).
令 \(d=k(a+b)\),将 \(k\) 放回求和内层,上面讨论可知 \(a\cdot d \le n\) 且 \(a\le n\),于是 \(a\le \sqrt{n}\),\(b\) 同理.
\[\sum_{a=1}^{\sqrt{n}}{\sum_{b=1}^{\sqrt{m}}{\sum_{k=1}^{\min(\left\lfloor\frac{n}{a(a+b)}\right\rfloor,\left\lfloor\frac{m}{b(a+b)}\right\rfloor)}{[\gcd(a,b)=1]}}}
\]
即
\[\sum_{a=1}^{\sqrt{n}}{\sum_{b=1}^{\sqrt{m}}{[\gcd(a,b)=1]\cdot \min(\left\lfloor\frac{n}{a(a+b)}\right\rfloor,\left\lfloor\frac{m}{b(a+b)}\right\rfloor)}}
\]
枚举 \(a,b\) 即可.
时间复杂度 \(\mathcal{O}(\sqrt{n\cdot m})\).
代码
//author:kzssCCC
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void solve(){
int n,m;
cin >> n >> m;
ll res = 0;
for (ll a=1;a*a<=n;a++){
for (ll b=1;b*b<=m;b++){
if (__gcd(a,b)==1){
res += min(n/(a*(a+b)),m/(b*(a+b)));
}
}
}
cout << res << '\n';
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t = 1;
cin >> t;
while (t--) solve();
return 0;
}

浙公网安备 33010602011771号