P7517 [省选联考 2021 B 卷] 数对
题面
给定 \(n\) 个正整数 \(a_i\),请你求出有多少个数对 \((i, j)\) 满足 \(1 \le i \le n\),\(1 \le j \le n\),\(i \ne j\) 且 \(a_i\) 是 \(a_j\) 的倍数。
输入格式
第一行,一个整数 \(n\),表示数字个数。
第二行,\(n\) 个整数,表示 \(a_i\)。
输出格式
输出一行,一个整数,表示答案。
提示说明
对于 \(40 \%\) 的数据,\(n \le 1000\)。
对于 \(70 \%\) 的数据,\(1 \le a_i \le 5 \times {10}^3\)。
对于 \(100 \%\) 的数据,\(2 \le n \le 2 \times {10}^5\),\(1 \le a_i \le 5 \times {10}^5\)。
思路
我永远都喜欢暴力!
枚举 \(i\),枚举 \(i\) 的因数 \(j\),然后数对就是 \((a_i \div j,j)\)。
记得答案要减一!
时间复杂度 \(O(n\sqrt{n})\)。
代码
#include <bits/stdc++.h>
#define CONTINUE continue
using namespace std;
int n;
int a[500005];
long long bucket[500005];
long long result;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
for(int j=1,aa,bb;j*j<=a[i];j++){
if(a[i]%j){
CONTINUE;
}
bucket[j]++;
if(j!=(a[i]/j)){
bucket[(a[i]/j)]++;
}
}
}
for(int i=1;i<=n;i++){
result+=(bucket[a[i]]-1ll);
}
cout<<result;
return 0;
}